| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is: all of this file. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): none yet. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 20:29:51 +00:00
										 |  |  | /** \file blender/editors/curve/editcurve.c
 | 
					
						
							|  |  |  |  *  \ingroup edcurve | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-16 05:46:10 +00:00
										 |  |  | #include "DNA_key_types.h"
 | 
					
						
							|  |  |  | #include "DNA_object_types.h"
 | 
					
						
							|  |  |  | #include "DNA_scene_types.h"
 | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | #include "DNA_anim_types.h"
 | 
					
						
							| 
									
										
										
										
											2010-08-16 05:46:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_blenlib.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | #include "BLI_math.h"
 | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | #include "BLI_ghash.h"
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-16 17:32:01 +10:00
										 |  |  | #include "BLT_translation.h"
 | 
					
						
							| 
									
										
										
										
											2013-02-24 15:40:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | #include "BKE_context.h"
 | 
					
						
							|  |  |  | #include "BKE_curve.h"
 | 
					
						
							|  |  |  | #include "BKE_depsgraph.h"
 | 
					
						
							| 
									
										
											  
											
												Move curve's boundbox and texspace calculation out of modifier stack
There were several issues with how bounding box and texture space
are calculated:
- This was done at the same time as applying modifiers, meaning if
  several objects are sharing the same curve datablock, bounding
  box and texture space will be calculated multiple times.
  Further, allocating bounding box wasn't safe for threading.
- Bounding box and texture space were evaluated after pre-tessellation
  modifiers are applied. This means Curve-level data is actually
  depends on object data, and it's really bad because different
  objects could have different modifiers and this leads to
  conflicts (curve's data depends on object evaluation order)
  and doesn't behave in a predictable way.
  This commit moves bounding box and texture space evaluation from
  modifier stack to own utility functions, just like it's was done
  for meshes.
  This makes curve objects update thread-safe, but gives some
  limitations as well. Namely, with such approach it's not so
  clear how to preserve the same behavior of texture space:
  before this change texture space and bounding box would match
  beveled curve as accurate as possible.
  Old behavior was nice for quick texturing -- in most cases you
  didn't need to modify texture space at all. But texture space
  was depending on render/preview settings which could easily lead
  to situations, when final result would be far different from
  preview one.
  Now we're using CV points coordinates and their radius to approximate
  the bounding box. This doesn't give the same exact texture space,
  but it helps a lot keeping texture space in a nice predictable way.
  We could make approximation smarter in the future, but fir now
  added operator to match texture space to fully tessellated curve
  called "Match Texture Space".
Review link:
  https://codereview.appspot.com/15410043/
Brief description:
  http://wiki.blender.org/index.php/User:Nazg-gul/GSoC-2013/Results#Curve_Texture_Space
											
										 
											2013-10-20 14:41:33 +02:00
										 |  |  | #include "BKE_displist.h"
 | 
					
						
							| 
									
										
											  
											
												2.5: Blender "Animato" - New Animation System 
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action. 
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves. 
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still) 
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
											
										 
											2009-01-17 03:12:50 +00:00
										 |  |  | #include "BKE_fcurve.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | #include "BKE_global.h"
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | #include "BKE_key.h"
 | 
					
						
							| 
									
										
										
										
											2015-11-09 19:47:10 +01:00
										 |  |  | #include "BKE_library.h"
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | #include "BKE_main.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | #include "BKE_report.h"
 | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | #include "BKE_animsys.h"
 | 
					
						
							| 
									
										
										
										
											2011-02-03 17:03:37 +00:00
										 |  |  | #include "BKE_action.h"
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | #include "BKE_modifier.h"
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-04 17:40:50 +00:00
										 |  |  | #include "WM_api.h"
 | 
					
						
							|  |  |  | #include "WM_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | #include "ED_keyframes_edit.h"
 | 
					
						
							|  |  |  | #include "ED_object.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | #include "ED_screen.h"
 | 
					
						
							| 
									
										
										
										
											2009-07-08 16:17:47 +00:00
										 |  |  | #include "ED_transform.h"
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | #include "ED_types.h"
 | 
					
						
							|  |  |  | #include "ED_util.h"
 | 
					
						
							|  |  |  | #include "ED_view3d.h"
 | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | #include "ED_curve.h"
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-14 17:55:27 +00:00
										 |  |  | #include "curve_intern.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | #include "UI_interface.h"
 | 
					
						
							| 
									
										
										
										
											2011-02-27 18:03:19 +00:00
										 |  |  | #include "UI_resources.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "RNA_access.h"
 | 
					
						
							|  |  |  | #include "RNA_define.h"
 | 
					
						
							| 
									
										
										
										
											2011-04-01 08:51:12 +00:00
										 |  |  | #include "RNA_enum_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | /* Undo stuff */ | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	ListBase nubase; | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 	int actvert; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	GHash *undoIndex; | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | 	ListBase fcurves, drivers; | 
					
						
							| 
									
										
										
										
											2011-02-14 03:36:15 +00:00
										 |  |  | 	int actnu; | 
					
						
							| 
									
										
										
										
											2014-11-20 18:58:24 +01:00
										 |  |  | 	int flag; | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | } UndoCurve; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | /* Definitions needed for shape keys */ | 
					
						
							|  |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 	void *orig_cv; | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 	int key_index, nu_index, pt_index, vertex_index; | 
					
						
							|  |  |  | 	bool switched; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 	Nurb *orig_nu; | 
					
						
							|  |  |  | } CVKeyIndex; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | void selectend_nurb(Object *obedit, enum eEndPoint_Types selfirst, bool doswap, bool selstatus); | 
					
						
							|  |  |  | static void adduplicateflagNurb(Object *obedit, ListBase *newnurb, const short flag, const bool split); | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | static int curve_delete_segments(Object *obedit, const bool split); | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-14 00:37:27 +00:00
										 |  |  | ListBase *object_editcurve_get(Object *ob) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (ob && ELEM(ob->type, OB_CURVE, OB_SURF)) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		Curve *cu = ob->data; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 		return &cu->editnurb->nurbs; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ******************* PRINTS ********************* */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-27 14:26:34 +11:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | void printknots(Object *obedit) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	int a, num; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 		if (ED_curve_nurb_select_check(nu) && nu->type == CU_NURBS) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (nu->knotsu) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				num = KNOTSU(nu); | 
					
						
							|  |  |  | 				for (a = 0; a < num; a++) printf("knotu %d: %f\n", a, nu->knotsu[a]); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (nu->knotsv) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				num = KNOTSV(nu); | 
					
						
							|  |  |  | 				for (a = 0; a < num; a++) printf("knotv %d: %f\n", a, nu->knotsv[a]); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-02-27 14:26:34 +11:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | /* ********************* Shape keys *************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | static CVKeyIndex *init_cvKeyIndex(void *cv, int key_index, int nu_index, int pt_index, int vertex_index, Nurb *orig_nu) | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 	CVKeyIndex *cvIndex = MEM_callocN(sizeof(CVKeyIndex), "init_cvKeyIndex"); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	cvIndex->orig_cv = cv; | 
					
						
							|  |  |  | 	cvIndex->key_index = key_index; | 
					
						
							|  |  |  | 	cvIndex->nu_index = nu_index; | 
					
						
							|  |  |  | 	cvIndex->pt_index = pt_index; | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 	cvIndex->vertex_index = vertex_index; | 
					
						
							|  |  |  | 	cvIndex->switched = false; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	cvIndex->orig_nu = orig_nu; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 	return cvIndex; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Nurb *nu = editnurb->nurbs.first; | 
					
						
							|  |  |  | 	Nurb *orignu = origBase->first; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	GHash *gh; | 
					
						
							|  |  |  | 	BezTriple *bezt, *origbezt; | 
					
						
							|  |  |  | 	BPoint *bp, *origbp; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 	CVKeyIndex *keyIndex; | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 	int a, key_index = 0, nu_index = 0, pt_index = 0, vertex_index = 0; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (editnurb->keyindex) return; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-16 00:51:36 +00:00
										 |  |  | 	gh = BLI_ghash_ptr_new("editNurb keyIndex"); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while (orignu) { | 
					
						
							|  |  |  | 		if (orignu->bezt) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			a = orignu->pntsu; | 
					
						
							|  |  |  | 			bezt = nu->bezt; | 
					
						
							|  |  |  | 			origbezt = orignu->bezt; | 
					
						
							|  |  |  | 			pt_index = 0; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			while (a--) { | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 				keyIndex = init_cvKeyIndex(origbezt, key_index, nu_index, pt_index, vertex_index, orignu); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 				BLI_ghash_insert(gh, bezt, keyIndex); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				key_index += 12; | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 				vertex_index += 3; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				bezt++; | 
					
						
							|  |  |  | 				origbezt++; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 				pt_index++; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			a = orignu->pntsu * orignu->pntsv; | 
					
						
							|  |  |  | 			bp = nu->bp; | 
					
						
							|  |  |  | 			origbp = orignu->bp; | 
					
						
							|  |  |  | 			pt_index = 0; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			while (a--) { | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 				keyIndex = init_cvKeyIndex(origbp, key_index, nu_index, pt_index, vertex_index, orignu); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 				BLI_ghash_insert(gh, bp, keyIndex); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				key_index += 4; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				bp++; | 
					
						
							|  |  |  | 				origbp++; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 				pt_index++; | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 				vertex_index++; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		nu = nu->next; | 
					
						
							|  |  |  | 		orignu = orignu->next; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 		nu_index++; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	editnurb->keyindex = gh; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-11 12:39:39 +10:00
										 |  |  | static CVKeyIndex *getCVKeyIndex(EditNurb *editnurb, const void *cv) | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 	return BLI_ghash_lookup(editnurb->keyindex, cv); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-11 12:39:39 +10:00
										 |  |  | static CVKeyIndex *popCVKeyIndex(EditNurb *editnurb, const void *cv) | 
					
						
							| 
									
										
										
										
											2012-05-28 19:33:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-08-26 23:37:08 +00:00
										 |  |  | 	return BLI_ghash_popkey(editnurb->keyindex, cv, NULL); | 
					
						
							| 
									
										
										
										
											2012-05-28 19:33:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-11 12:39:39 +10:00
										 |  |  | static BezTriple *getKeyIndexOrig_bezt(EditNurb *editnurb, const BezTriple *bezt) | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	CVKeyIndex *index = getCVKeyIndex(editnurb, bezt); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!index) { | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	return (BezTriple *)index->orig_cv; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | static BPoint *getKeyIndexOrig_bp(EditNurb *editnurb, BPoint *bp) | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	CVKeyIndex *index = getCVKeyIndex(editnurb, bp); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!index) { | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	return (BPoint *)index->orig_cv; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | static int getKeyIndexOrig_keyIndex(EditNurb *editnurb, void *cv) | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	CVKeyIndex *index = getCVKeyIndex(editnurb, cv); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!index) { | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 	return index->key_index; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-11 12:39:39 +10:00
										 |  |  | static void keyIndex_delCV(EditNurb *editnurb, const void *cv) | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (!editnurb->keyindex) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-21 08:45:10 +00:00
										 |  |  | 	BLI_ghash_remove(editnurb->keyindex, cv, NULL, MEM_freeN); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void keyIndex_delBezt(EditNurb *editnurb, BezTriple *bezt) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 	keyIndex_delCV(editnurb, bezt); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void keyIndex_delBP(EditNurb *editnurb, BPoint *bp) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 	keyIndex_delCV(editnurb, bp); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void keyIndex_delNurb(EditNurb *editnurb, Nurb *nu) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-03 23:04:45 +00:00
										 |  |  | 	if (!editnurb->keyindex) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	if (nu->bezt) { | 
					
						
							| 
									
										
										
										
											2015-05-11 12:39:39 +10:00
										 |  |  | 		const BezTriple *bezt = nu->bezt; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		a = nu->pntsu; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		while (a--) { | 
					
						
							| 
									
										
										
										
											2013-05-21 08:45:10 +00:00
										 |  |  | 			BLI_ghash_remove(editnurb->keyindex, bezt, NULL, MEM_freeN); | 
					
						
							| 
									
										
										
										
											2012-05-09 09:24:15 +00:00
										 |  |  | 			bezt++; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2015-05-11 12:39:39 +10:00
										 |  |  | 		const BPoint *bp = nu->bp; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		a = nu->pntsu * nu->pntsv; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		while (a--) { | 
					
						
							| 
									
										
										
										
											2013-05-21 08:45:10 +00:00
										 |  |  | 			BLI_ghash_remove(editnurb->keyindex, bp, NULL, MEM_freeN); | 
					
						
							| 
									
										
										
										
											2012-05-09 09:24:15 +00:00
										 |  |  | 			bp++; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void keyIndex_delNurbList(EditNurb *editnurb, ListBase *nubase) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Nurb *nu = nubase->first; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while (nu) { | 
					
						
							|  |  |  | 		keyIndex_delNurb(editnurb, nu); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		nu = nu->next; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | static void keyIndex_updateCV(EditNurb *editnurb, char *cv, | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  |                               char *newcv, int count, int size) | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 	CVKeyIndex *index; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (editnurb->keyindex == NULL) { | 
					
						
							|  |  |  | 		/* No shape keys - updating not needed */ | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < count; i++) { | 
					
						
							| 
									
										
										
										
											2012-05-28 19:33:14 +00:00
										 |  |  | 		index = popCVKeyIndex(editnurb, cv); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (index) { | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 			BLI_ghash_insert(editnurb->keyindex, newcv, index); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 		newcv += size; | 
					
						
							|  |  |  | 		cv += size; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void keyIndex_updateBezt(EditNurb *editnurb, BezTriple *bezt, | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  |                                 BezTriple *newbezt, int count) | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	keyIndex_updateCV(editnurb, (char *)bezt, (char *)newbezt, count, sizeof(BezTriple)); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void keyIndex_updateBP(EditNurb *editnurb, BPoint *bp, | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  |                               BPoint *newbp, int count) | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	keyIndex_updateCV(editnurb, (char *)bp, (char *)newbp, count, sizeof(BPoint)); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void keyIndex_updateNurb(EditNurb *editnurb, Nurb *nu, Nurb *newnu) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (nu->bezt) { | 
					
						
							| 
									
										
										
										
											2010-12-06 21:18:08 +00:00
										 |  |  | 		keyIndex_updateBezt(editnurb, nu->bezt, newnu->bezt, newnu->pntsu); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2010-12-06 21:18:08 +00:00
										 |  |  | 		keyIndex_updateBP(editnurb, nu->bp, newnu->bp, newnu->pntsu * newnu->pntsv); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void keyIndex_swap(EditNurb *editnurb, void *a, void *b) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-28 19:33:14 +00:00
										 |  |  | 	CVKeyIndex *index1 = popCVKeyIndex(editnurb, a); | 
					
						
							|  |  |  | 	CVKeyIndex *index2 = popCVKeyIndex(editnurb, b); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (index2) BLI_ghash_insert(editnurb->keyindex, a, index2); | 
					
						
							|  |  |  | 	if (index1) BLI_ghash_insert(editnurb->keyindex, b, index1); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void keyIndex_switchDirection(EditNurb *editnurb, Nurb *nu) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int a; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 	CVKeyIndex *index1, *index2; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (nu->bezt) { | 
					
						
							|  |  |  | 		BezTriple *bezt1, *bezt2; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		a = nu->pntsu; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		bezt1 = nu->bezt; | 
					
						
							|  |  |  | 		bezt2 = bezt1 + (a - 1); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (a & 1) ++a; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		a /= 2; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		while (a--) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			index1 = getCVKeyIndex(editnurb, bezt1); | 
					
						
							|  |  |  | 			index2 = getCVKeyIndex(editnurb, bezt2); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			if (index1) index1->switched = !index1->switched; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			if (bezt1 != bezt2) { | 
					
						
							|  |  |  | 				keyIndex_swap(editnurb, bezt1, bezt2); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				if (index2) index2->switched = !index2->switched; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			bezt1++; | 
					
						
							|  |  |  | 			bezt2--; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 		BPoint *bp1, *bp2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (nu->pntsv == 1) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			a = nu->pntsu; | 
					
						
							|  |  |  | 			bp1 = nu->bp; | 
					
						
							|  |  |  | 			bp2 = bp1 + (a - 1); | 
					
						
							|  |  |  | 			a /= 2; | 
					
						
							|  |  |  | 			while (bp1 != bp2 && a > 0) { | 
					
						
							|  |  |  | 				index1 = getCVKeyIndex(editnurb, bp1); | 
					
						
							|  |  |  | 				index2 = getCVKeyIndex(editnurb, bp2); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				if (index1) index1->switched = !index1->switched; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				if (bp1 != bp2) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					if (index2) index2->switched = !index2->switched; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 					keyIndex_swap(editnurb, bp1, bp2); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				a--; | 
					
						
							|  |  |  | 				bp1++; | 
					
						
							|  |  |  | 				bp2--; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			int b; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			for (b = 0; b < nu->pntsv; b++) { | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				bp1 = &nu->bp[b * nu->pntsu]; | 
					
						
							|  |  |  | 				a = nu->pntsu; | 
					
						
							|  |  |  | 				bp2 = bp1 + (a - 1); | 
					
						
							|  |  |  | 				a /= 2; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				while (bp1 != bp2 && a > 0) { | 
					
						
							|  |  |  | 					index1 = getCVKeyIndex(editnurb, bp1); | 
					
						
							|  |  |  | 					index2 = getCVKeyIndex(editnurb, bp2); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					if (index1) index1->switched = !index1->switched; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 					if (bp1 != bp2) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						if (index2) index2->switched = !index2->switched; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 						keyIndex_swap(editnurb, bp1, bp2); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					a--; | 
					
						
							|  |  |  | 					bp1++; | 
					
						
							|  |  |  | 					bp2--; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void switch_keys_direction(Curve *cu, Nurb *actnu) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	KeyBlock *currkey; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	EditNurb *editnurb = cu->editnurb; | 
					
						
							|  |  |  | 	ListBase *nubase = &editnurb->nurbs; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	float *fp; | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	currkey = cu->key->block.first; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (currkey) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		fp = currkey->data; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		nu = nubase->first; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 		while (nu) { | 
					
						
							|  |  |  | 			if (nu->bezt) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				BezTriple *bezt = nu->bezt; | 
					
						
							|  |  |  | 				a = nu->pntsu; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				if (nu == actnu) { | 
					
						
							|  |  |  | 					while (a--) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 						if (getKeyIndexOrig_bezt(editnurb, bezt)) { | 
					
						
							| 
									
										
										
										
											2010-12-06 13:44:36 +00:00
										 |  |  | 							swap_v3_v3(fp, fp + 6); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							*(fp + 9) = -*(fp + 9); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:44:36 +00:00
										 |  |  | 							fp += 12; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						bezt++; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 				else { | 
					
						
							|  |  |  | 					fp += a * 12; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				BPoint *bp = nu->bp; | 
					
						
							|  |  |  | 				a = nu->pntsu * nu->pntsv; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				if (nu == actnu) { | 
					
						
							|  |  |  | 					while (a--) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 						if (getKeyIndexOrig_bp(editnurb, bp)) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							*(fp + 3) = -*(fp + 3); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:44:36 +00:00
										 |  |  | 							fp += 4; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						bp++; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 				else { | 
					
						
							|  |  |  | 					fp += a * 4; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			nu = nu->next; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		currkey = currkey->next; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void keyData_switchDirectionNurb(Curve *cu, Nurb *nu) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	EditNurb *editnurb = cu->editnurb; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!editnurb->keyindex) { | 
					
						
							|  |  |  | 		/* no shape keys - nothing to do */ | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	keyIndex_switchDirection(editnurb, nu); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (cu->key) | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 		switch_keys_direction(cu, nu); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static GHash *dupli_keyIndexHash(GHash *keyindex) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	GHash *gh; | 
					
						
							| 
									
										
										
										
											2015-02-06 15:31:08 +11:00
										 |  |  | 	GHashIterator gh_iter; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-24 17:33:47 +00:00
										 |  |  | 	gh = BLI_ghash_ptr_new_ex("dupli_keyIndex gh", BLI_ghash_size(keyindex)); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-06 15:31:08 +11:00
										 |  |  | 	GHASH_ITER (gh_iter, keyindex) { | 
					
						
							|  |  |  | 		void *cv = BLI_ghashIterator_getKey(&gh_iter); | 
					
						
							|  |  |  | 		CVKeyIndex *index = BLI_ghashIterator_getValue(&gh_iter); | 
					
						
							|  |  |  | 		CVKeyIndex *newIndex = MEM_mallocN(sizeof(CVKeyIndex), "dupli_keyIndexHash index"); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 		memcpy(newIndex, index, sizeof(CVKeyIndex)); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 		BLI_ghash_insert(gh, cv, newIndex); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return gh; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void key_to_bezt(float *key, BezTriple *basebezt, BezTriple *bezt) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	memcpy(bezt, basebezt, sizeof(BezTriple)); | 
					
						
							|  |  |  | 	memcpy(bezt->vec, key, sizeof(float) * 9); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	bezt->alfa = key[9]; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void bezt_to_key(BezTriple *bezt, float *key) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-11-11 13:09:14 +00:00
										 |  |  | 	memcpy(key, bezt->vec, sizeof(float) * 9); | 
					
						
							|  |  |  | 	key[9] = bezt->alfa; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void calc_keyHandles(ListBase *nurb, float *key) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	int a; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	float *fp = key; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	BezTriple *bezt; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	nu = nurb->first; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	while (nu) { | 
					
						
							|  |  |  | 		if (nu->bezt) { | 
					
						
							|  |  |  | 			BezTriple *prevp, *nextp; | 
					
						
							|  |  |  | 			BezTriple cur, prev, next; | 
					
						
							|  |  |  | 			float *startfp, *prevfp, *nextfp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			bezt = nu->bezt; | 
					
						
							|  |  |  | 			a = nu->pntsu; | 
					
						
							|  |  |  | 			startfp = fp; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (nu->flagu & CU_NURB_CYCLIC) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				prevp = bezt + (a - 1); | 
					
						
							|  |  |  | 				prevfp = fp + (12 * (a - 1)); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				prevp = NULL; | 
					
						
							|  |  |  | 				prevfp = NULL; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			nextp = bezt + 1; | 
					
						
							|  |  |  | 			nextfp = fp + 12; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			while (a--) { | 
					
						
							|  |  |  | 				key_to_bezt(fp, bezt, &cur); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (nextp) key_to_bezt(nextfp, nextp, &next); | 
					
						
							|  |  |  | 				if (prevp) key_to_bezt(prevfp, prevp, &prev); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 				BKE_nurb_handle_calc(&cur, prevp ? &prev : NULL, nextp ? &next : NULL, 0); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				bezt_to_key(&cur, fp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				prevp = bezt; | 
					
						
							|  |  |  | 				prevfp = fp; | 
					
						
							|  |  |  | 				if (a == 1) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					if (nu->flagu & CU_NURB_CYCLIC) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						nextp = nu->bezt; | 
					
						
							|  |  |  | 						nextfp = startfp; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						nextp = NULL; | 
					
						
							|  |  |  | 						nextfp = NULL; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							| 
									
										
										
										
											2012-05-09 09:24:15 +00:00
										 |  |  | 					nextp++; | 
					
						
							| 
									
										
										
										
											2010-12-03 01:52:28 +00:00
										 |  |  | 					nextfp += 12; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-09 09:24:15 +00:00
										 |  |  | 				bezt++; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				fp += 12; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			a = nu->pntsu * nu->pntsv; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			fp += a * 4; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		nu = nu->next; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void calc_shapeKeys(Object *obedit) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Curve *cu = (Curve *)obedit->data; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* are there keys? */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (cu->key) { | 
					
						
							| 
									
										
										
										
											2011-05-23 08:14:29 +00:00
										 |  |  | 		int a, i; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		EditNurb *editnurb = cu->editnurb; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 		KeyBlock *currkey; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		KeyBlock *actkey = BLI_findlink(&cu->key->block, editnurb->shapenr - 1); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 		BezTriple *bezt, *oldbezt; | 
					
						
							|  |  |  | 		BPoint *bp, *oldbp; | 
					
						
							|  |  |  | 		Nurb *nu; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		int totvert = BKE_nurbList_verts_count(&editnurb->nurbs); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		float (*ofs)[3] = NULL; | 
					
						
							| 
									
										
										
										
											2010-10-07 10:04:07 +00:00
										 |  |  | 		float *oldkey, *newkey, *ofp; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* editing the base key should update others */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		if (cu->key->type == KEY_RELATIVE) { | 
					
						
							| 
									
										
										
										
											2014-11-16 21:45:40 +01:00
										 |  |  | 			if (BKE_keyblock_is_basis(cu->key, editnurb->shapenr - 1)) { /* active key is a base */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				int totvec = 0; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* Calculate needed memory to store offset */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				nu = editnurb->nurbs.first; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				while (nu) { | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 					if (nu->bezt) { | 
					
						
							|  |  |  | 						/* Three vects to store handles and one for alfa */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						totvec += nu->pntsu * 4; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						totvec += 2 * nu->pntsu * nu->pntsv; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					nu = nu->next; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				ofs = MEM_callocN(sizeof(float) * 3 * totvec,  "currkey->data"); | 
					
						
							|  |  |  | 				nu = editnurb->nurbs.first; | 
					
						
							|  |  |  | 				i = 0; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				while (nu) { | 
					
						
							|  |  |  | 					if (nu->bezt) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						bezt = nu->bezt; | 
					
						
							|  |  |  | 						a = nu->pntsu; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 						while (a--) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							oldbezt = getKeyIndexOrig_bezt(editnurb, bezt); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 							if (oldbezt) { | 
					
						
							| 
									
										
										
										
											2011-05-23 08:14:29 +00:00
										 |  |  | 								int j; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 								for (j = 0; j < 3; ++j) { | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 									sub_v3_v3v3(ofs[i], bezt->vec[j], oldbezt->vec[j]); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 									i++; | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 								ofs[i++][0] = bezt->alfa - oldbezt->alfa; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 							} | 
					
						
							|  |  |  | 							else { | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 								i += 4; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							bezt++; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						bp = nu->bp; | 
					
						
							|  |  |  | 						a = nu->pntsu * nu->pntsv; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 						while (a--) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							oldbp = getKeyIndexOrig_bp(editnurb, bp); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 							if (oldbp) { | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 								sub_v3_v3v3(ofs[i], bp->vec, oldbp->vec); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 								ofs[i + 1][0] = bp->alfa - oldbp->alfa; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 							} | 
					
						
							|  |  |  | 							i += 2; | 
					
						
							| 
									
										
										
										
											2012-05-09 09:24:15 +00:00
										 |  |  | 							bp++; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					nu = nu->next; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		currkey = cu->key->block.first; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		while (currkey) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			int apply_offset = (ofs && (currkey != actkey) && (editnurb->shapenr - 1 == currkey->relative)); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			float *fp = newkey = MEM_callocN(cu->key->elemsize * totvert,  "currkey->data"); | 
					
						
							|  |  |  | 			ofp = oldkey = currkey->data; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			nu = editnurb->nurbs.first; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			i = 0; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (nu) { | 
					
						
							|  |  |  | 				if (currkey == actkey) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					int restore = actkey != cu->key->refkey; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					if (nu->bezt) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						bezt = nu->bezt; | 
					
						
							|  |  |  | 						a = nu->pntsu; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 						while (a--) { | 
					
						
							| 
									
										
										
										
											2011-05-23 08:14:29 +00:00
										 |  |  | 							int j; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							oldbezt = getKeyIndexOrig_bezt(editnurb, bezt); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							for (j = 0; j < 3; ++j, ++i) { | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 								copy_v3_v3(fp, bezt->vec[j]); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 								if (restore && oldbezt) { | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 									copy_v3_v3(bezt->vec[j], oldbezt->vec[j]); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 								} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 								fp += 3; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							fp[0] = bezt->alfa; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 							if (restore && oldbezt) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 								bezt->alfa = oldbezt->alfa; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 							} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							fp += 3; ++i; /* alphas */ | 
					
						
							| 
									
										
										
										
											2012-05-09 09:24:15 +00:00
										 |  |  | 							bezt++; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						bp = nu->bp; | 
					
						
							|  |  |  | 						a = nu->pntsu * nu->pntsv; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 						while (a--) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							oldbp = getKeyIndexOrig_bp(editnurb, bp); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 							copy_v3_v3(fp, bp->vec); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							fp[3] = bp->alfa; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 							if (restore && oldbp) { | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 								copy_v3_v3(bp->vec, oldbp->vec); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 								bp->alfa = oldbp->alfa; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 							} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							fp += 4; | 
					
						
							| 
									
										
										
										
											2012-05-09 09:24:15 +00:00
										 |  |  | 							bp++; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							i += 2; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					int index; | 
					
						
							| 
									
										
										
										
											2014-04-27 00:22:49 +10:00
										 |  |  | 					const float *curofp; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					if (oldkey) { | 
					
						
							|  |  |  | 						if (nu->bezt) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							bezt = nu->bezt; | 
					
						
							|  |  |  | 							a = nu->pntsu; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 							while (a--) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 								index = getKeyIndexOrig_keyIndex(editnurb, bezt); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 								if (index >= 0) { | 
					
						
							| 
									
										
										
										
											2011-05-23 08:14:29 +00:00
										 |  |  | 									int j; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 									curofp = ofp + index; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 									for (j = 0; j < 3; ++j, ++i) { | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 										copy_v3_v3(fp, curofp); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 										if (apply_offset) { | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 											add_v3_v3(fp, ofs[i]); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 										} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 										fp += 3; curofp += 3; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 									} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 									fp[0] = curofp[0]; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 									if (apply_offset) { | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 										/* apply alfa offsets */ | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 										add_v3_v3(fp, ofs[i]); | 
					
						
							| 
									
										
										
										
											2012-05-09 09:24:15 +00:00
										 |  |  | 										i++; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 									} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 									fp += 3; /* alphas */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 								} | 
					
						
							|  |  |  | 								else { | 
					
						
							| 
									
										
										
										
											2011-05-23 08:14:29 +00:00
										 |  |  | 									int j; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 									for (j = 0; j < 3; ++j, ++i) { | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 										copy_v3_v3(fp, bezt->vec[j]); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 										fp += 3; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 									} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 									fp[0] = bezt->alfa; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 									fp += 3; /* alphas */ | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2012-05-09 09:24:15 +00:00
										 |  |  | 								bezt++; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							bp = nu->bp; | 
					
						
							|  |  |  | 							a = nu->pntsu * nu->pntsv; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 							while (a--) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 								index = getKeyIndexOrig_keyIndex(editnurb, bp); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 								if (index >= 0) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 									curofp = ofp + index; | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 									copy_v3_v3(fp, curofp); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 									fp[3] = curofp[3]; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 									if (apply_offset) { | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 										add_v3_v3(fp, ofs[i]); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 										fp[3] += ofs[i + 1][0]; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 									} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 								} | 
					
						
							|  |  |  | 								else { | 
					
						
							| 
									
										
										
										
											2011-11-06 15:17:43 +00:00
										 |  |  | 									copy_v3_v3(fp, bp->vec); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 									fp[3] = bp->alfa; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 								} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 								fp += 4; | 
					
						
							| 
									
										
										
										
											2012-05-09 09:24:15 +00:00
										 |  |  | 								bp++; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 								i += 2; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				nu = nu->next; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (apply_offset) { | 
					
						
							|  |  |  | 				/* handles could become malicious after offsets applying */ | 
					
						
							|  |  |  | 				calc_keyHandles(&editnurb->nurbs, newkey); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			currkey->totelem = totvert; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (currkey->data) MEM_freeN(currkey->data); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			currkey->data = newkey; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			currkey = currkey->next; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (ofs) MEM_freeN(ofs); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | /* ********************* Amimation data *************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-05 22:36:15 +11:00
										 |  |  | static bool curve_is_animated(Curve *cu) | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	AnimData *ad = BKE_animdata_from_id(&cu->id); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | 	return ad && (ad->action || ad->drivers.first); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-13 04:28:04 +00:00
										 |  |  | static void fcurve_path_rename(AnimData *adt, const char *orig_rna_path, char *rna_path, | 
					
						
							|  |  |  |                                ListBase *orig_curves, ListBase *curves) | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	FCurve *fcu, *nfcu, *nextfcu; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	int len = strlen(orig_rna_path); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-21 06:17:20 +00:00
										 |  |  | 	for (fcu = orig_curves->first; fcu; fcu = nextfcu) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		nextfcu = fcu->next; | 
					
						
							| 
									
										
										
										
											2015-01-26 16:03:11 +01:00
										 |  |  | 		if (STREQLEN(fcu->rna_path, orig_rna_path, len)) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			char *spath, *suffix = fcu->rna_path + len; | 
					
						
							|  |  |  | 			nfcu = copy_fcurve(fcu); | 
					
						
							|  |  |  | 			spath = nfcu->rna_path; | 
					
						
							|  |  |  | 			nfcu->rna_path = BLI_sprintfN("%s%s", rna_path, suffix); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 			BLI_addtail(curves, nfcu); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-03 17:03:37 +00:00
										 |  |  | 			if (fcu->grp) { | 
					
						
							| 
									
										
										
										
											2012-12-21 06:17:20 +00:00
										 |  |  | 				action_groups_remove_channel(adt->action, fcu); | 
					
						
							|  |  |  | 				action_groups_add_channel(adt->action, fcu->grp, nfcu); | 
					
						
							| 
									
										
										
										
											2011-02-03 17:03:37 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-12-21 06:17:20 +00:00
										 |  |  | 			else if ((adt->action) && (&adt->action->curves == orig_curves)) | 
					
						
							|  |  |  | 				BLI_remlink(&adt->action->curves, fcu); | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | 			else | 
					
						
							| 
									
										
										
										
											2012-12-21 06:17:20 +00:00
										 |  |  | 				BLI_remlink(&adt->drivers, fcu); | 
					
						
							| 
									
										
										
										
											2011-02-03 17:03:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 			free_fcurve(fcu); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			MEM_freeN(spath); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-21 06:17:20 +00:00
										 |  |  | static void fcurve_remove(AnimData *adt, ListBase *orig_curves, FCurve *fcu) | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-12-21 06:17:20 +00:00
										 |  |  | 	if (orig_curves == &adt->drivers) BLI_remlink(&adt->drivers, fcu); | 
					
						
							|  |  |  | 	else action_groups_remove_channel(adt->action, fcu); | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	free_fcurve(fcu); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-16 08:04:12 +00:00
										 |  |  | static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves) | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	int nu_index = 0, a, pt_index; | 
					
						
							|  |  |  | 	EditNurb *editnurb = cu->editnurb; | 
					
						
							| 
									
										
										
										
											2014-06-26 15:46:42 +10:00
										 |  |  | 	Nurb *nu; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 	CVKeyIndex *keyIndex; | 
					
						
							|  |  |  | 	char rna_path[64], orig_rna_path[64]; | 
					
						
							| 
									
										
										
										
											2012-11-22 22:58:01 +00:00
										 |  |  | 	AnimData *adt = BKE_animdata_from_id(&cu->id); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ListBase curves = {NULL, NULL}; | 
					
						
							| 
									
										
										
										
											2010-12-20 19:47:16 +00:00
										 |  |  | 	FCurve *fcu, *next; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-21 06:17:20 +00:00
										 |  |  | 	for (nu = editnurb->nurbs.first, nu_index = 0;  nu != NULL;  nu = nu->next, nu_index++) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (nu->bezt) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			BezTriple *bezt = nu->bezt; | 
					
						
							|  |  |  | 			a = nu->pntsu; | 
					
						
							|  |  |  | 			pt_index = 0; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			while (a--) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				keyIndex = getCVKeyIndex(editnurb, bezt); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (keyIndex) { | 
					
						
							| 
									
										
										
										
											2012-01-11 12:33:51 +00:00
										 |  |  | 					BLI_snprintf(rna_path, sizeof(rna_path), "splines[%d].bezier_points[%d]", nu_index, pt_index); | 
					
						
							|  |  |  | 					BLI_snprintf(orig_rna_path, sizeof(orig_rna_path), "splines[%d].bezier_points[%d]", keyIndex->nu_index, keyIndex->pt_index); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					if (keyIndex->switched) { | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 						char handle_path[64], orig_handle_path[64]; | 
					
						
							| 
									
										
										
										
											2012-01-11 12:33:51 +00:00
										 |  |  | 						BLI_snprintf(orig_handle_path, sizeof(orig_rna_path), "%s.handle_left", orig_rna_path); | 
					
						
							|  |  |  | 						BLI_snprintf(handle_path, sizeof(rna_path), "%s.handle_right", rna_path); | 
					
						
							| 
									
										
										
										
											2012-11-22 22:58:01 +00:00
										 |  |  | 						fcurve_path_rename(adt, orig_handle_path, handle_path, orig_curves, &curves); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-11 12:33:51 +00:00
										 |  |  | 						BLI_snprintf(orig_handle_path, sizeof(orig_rna_path), "%s.handle_right", orig_rna_path); | 
					
						
							|  |  |  | 						BLI_snprintf(handle_path, sizeof(rna_path), "%s.handle_left", rna_path); | 
					
						
							| 
									
										
										
										
											2012-11-22 22:58:01 +00:00
										 |  |  | 						fcurve_path_rename(adt, orig_handle_path, handle_path, orig_curves, &curves); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-22 22:58:01 +00:00
										 |  |  | 					fcurve_path_rename(adt, orig_rna_path, rna_path, orig_curves, &curves); | 
					
						
							| 
									
										
										
										
											2010-12-20 19:47:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					keyIndex->nu_index = nu_index; | 
					
						
							|  |  |  | 					keyIndex->pt_index = pt_index; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				bezt++; | 
					
						
							|  |  |  | 				pt_index++; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			BPoint *bp = nu->bp; | 
					
						
							|  |  |  | 			a = nu->pntsu * nu->pntsv; | 
					
						
							|  |  |  | 			pt_index = 0; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			while (a--) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				keyIndex = getCVKeyIndex(editnurb, bp); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (keyIndex) { | 
					
						
							| 
									
										
										
										
											2012-01-11 12:33:51 +00:00
										 |  |  | 					BLI_snprintf(rna_path, sizeof(rna_path), "splines[%d].points[%d]", nu_index, pt_index); | 
					
						
							|  |  |  | 					BLI_snprintf(orig_rna_path, sizeof(orig_rna_path), "splines[%d].points[%d]", keyIndex->nu_index, keyIndex->pt_index); | 
					
						
							| 
									
										
										
										
											2012-11-22 22:58:01 +00:00
										 |  |  | 					fcurve_path_rename(adt, orig_rna_path, rna_path, orig_curves, &curves); | 
					
						
							| 
									
										
										
										
											2010-12-20 19:47:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					keyIndex->nu_index = nu_index; | 
					
						
							|  |  |  | 					keyIndex->pt_index = pt_index; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				bp++; | 
					
						
							|  |  |  | 				pt_index++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-04 04:35:12 +00:00
										 |  |  | 	/* remove paths for removed control points
 | 
					
						
							| 
									
										
										
										
											2012-03-03 16:31:46 +00:00
										 |  |  | 	 * need this to make further step with copying non-cv related curves copying | 
					
						
							| 
									
										
										
										
											2012-03-04 04:35:12 +00:00
										 |  |  | 	 * not touching cv's f-curves */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (fcu = orig_curves->first; fcu; fcu = next) { | 
					
						
							|  |  |  | 		next = fcu->next; | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 16:03:11 +01:00
										 |  |  | 		if (STREQLEN(fcu->rna_path, "splines", 7)) { | 
					
						
							| 
									
										
										
										
											2014-04-27 00:22:49 +10:00
										 |  |  | 			const char *ch = strchr(fcu->rna_path, '.'); | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 16:03:11 +01:00
										 |  |  | 			if (ch && (STREQLEN(ch, ".bezier_points", 14) || STREQLEN(ch, ".points", 7))) | 
					
						
							| 
									
										
										
										
											2012-11-22 22:58:01 +00:00
										 |  |  | 				fcurve_remove(adt, orig_curves, fcu); | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-21 06:17:20 +00:00
										 |  |  | 	for (nu = editnurb->nurbs.first, nu_index = 0;  nu != NULL;  nu = nu->next, nu_index++) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		keyIndex = NULL; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (nu->pntsu) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			if (nu->bezt) keyIndex = getCVKeyIndex(editnurb, &nu->bezt[0]); | 
					
						
							|  |  |  | 			else keyIndex = getCVKeyIndex(editnurb, &nu->bp[0]); | 
					
						
							| 
									
										
										
										
											2011-02-03 17:03:37 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (keyIndex) { | 
					
						
							| 
									
										
										
										
											2012-01-11 12:33:51 +00:00
										 |  |  | 			BLI_snprintf(rna_path, sizeof(rna_path), "splines[%d]", nu_index); | 
					
						
							|  |  |  | 			BLI_snprintf(orig_rna_path, sizeof(orig_rna_path), "splines[%d]", keyIndex->nu_index); | 
					
						
							| 
									
										
										
										
											2012-11-22 22:58:01 +00:00
										 |  |  | 			fcurve_path_rename(adt, orig_rna_path, rna_path, orig_curves, &curves); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-13 17:10:44 +00:00
										 |  |  | 	/* the remainders in orig_curves can be copied back (like follow path) */ | 
					
						
							| 
									
										
										
										
											2010-12-20 19:47:16 +00:00
										 |  |  | 	/* (if it's not path to spline) */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (fcu = orig_curves->first; fcu; fcu = next) { | 
					
						
							|  |  |  | 		next = fcu->next; | 
					
						
							| 
									
										
										
										
											2010-12-20 19:47:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 16:03:11 +01:00
										 |  |  | 		if (STREQLEN(fcu->rna_path, "splines", 7)) fcurve_remove(adt, orig_curves, fcu); | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | 		else BLI_addtail(&curves, fcu); | 
					
						
							| 
									
										
										
										
											2010-12-20 19:47:16 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	*orig_curves = curves; | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* return 0 if animation data wasn't changed, 1 otherwise */ | 
					
						
							| 
									
										
										
										
											2012-04-16 08:04:12 +00:00
										 |  |  | int ED_curve_updateAnimPaths(Curve *cu) | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-11-22 22:58:01 +00:00
										 |  |  | 	AnimData *adt = BKE_animdata_from_id(&cu->id); | 
					
						
							| 
									
										
										
										
											2013-05-27 10:08:56 +00:00
										 |  |  | 	EditNurb *editnurb = cu->editnurb; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!editnurb->keyindex) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-16 08:04:12 +00:00
										 |  |  | 	if (!curve_is_animated(cu)) return 0; | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-22 22:58:01 +00:00
										 |  |  | 	if (adt->action) | 
					
						
							|  |  |  | 		curve_rename_fcurves(cu, &adt->action->curves); | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-22 22:58:01 +00:00
										 |  |  | 	curve_rename_fcurves(cu, &adt->drivers); | 
					
						
							| 
									
										
										
										
											2010-12-20 19:47:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | /* ********************* LOAD and MAKE *************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 10:56:20 +06:00
										 |  |  | static int *initialize_index_map(Object *obedit, int *r_old_totvert) | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | { | 
					
						
							|  |  |  | 	Curve *curve = (Curve *) obedit->data; | 
					
						
							|  |  |  | 	EditNurb *editnurb = curve->editnurb; | 
					
						
							|  |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	CVKeyIndex *keyIndex; | 
					
						
							|  |  |  | 	int *old_to_new_map; | 
					
						
							|  |  |  | 	int old_totvert, i; | 
					
						
							|  |  |  | 	int vertex_index; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (nu = curve->nurb.first, old_totvert = 0; nu != NULL; nu = nu->next) { | 
					
						
							|  |  |  | 		if (nu->bezt) { | 
					
						
							|  |  |  | 			old_totvert += nu->pntsu * 3; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			old_totvert += nu->pntsu * nu->pntsv; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	old_to_new_map = MEM_mallocN(old_totvert * sizeof(int), "curve old to new index map"); | 
					
						
							|  |  |  | 	for (i = 0; i < old_totvert; i++) { | 
					
						
							|  |  |  | 		old_to_new_map[i] = -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (nu = editnurb->nurbs.first, vertex_index = 0; | 
					
						
							|  |  |  | 	     nu != NULL; | 
					
						
							| 
									
										
										
										
											2014-07-18 14:44:05 +06:00
										 |  |  | 	     nu = nu->next) | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		if (nu->bezt) { | 
					
						
							|  |  |  | 			BezTriple *bezt = nu->bezt; | 
					
						
							|  |  |  | 			int a = nu->pntsu; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			while (a--) { | 
					
						
							|  |  |  | 				keyIndex = getCVKeyIndex(editnurb, bezt); | 
					
						
							| 
									
										
										
										
											2015-05-27 13:07:24 +05:00
										 |  |  | 				if (keyIndex && keyIndex->vertex_index + 2 < old_totvert) { | 
					
						
							| 
									
										
										
										
											2014-08-01 10:56:20 +06:00
										 |  |  | 					if (keyIndex->switched) { | 
					
						
							|  |  |  | 						old_to_new_map[keyIndex->vertex_index] = vertex_index + 2; | 
					
						
							|  |  |  | 						old_to_new_map[keyIndex->vertex_index + 1] = vertex_index + 1; | 
					
						
							|  |  |  | 						old_to_new_map[keyIndex->vertex_index + 2] = vertex_index; | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2014-08-01 10:56:20 +06:00
										 |  |  | 						old_to_new_map[keyIndex->vertex_index] = vertex_index; | 
					
						
							|  |  |  | 						old_to_new_map[keyIndex->vertex_index + 1] = vertex_index + 1; | 
					
						
							|  |  |  | 						old_to_new_map[keyIndex->vertex_index + 2] = vertex_index + 2; | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				vertex_index += 3; | 
					
						
							|  |  |  | 				bezt++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			BPoint *bp = nu->bp; | 
					
						
							|  |  |  | 			int a = nu->pntsu * nu->pntsv; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			while (a--) { | 
					
						
							|  |  |  | 				keyIndex = getCVKeyIndex(editnurb, bp); | 
					
						
							|  |  |  | 				if (keyIndex) { | 
					
						
							| 
									
										
										
										
											2014-08-01 10:56:20 +06:00
										 |  |  | 					old_to_new_map[keyIndex->vertex_index] = vertex_index; | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				vertex_index++; | 
					
						
							|  |  |  | 				bp++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-16 03:24:05 +11:00
										 |  |  | 	*r_old_totvert = old_totvert; | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 	return old_to_new_map; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 10:56:20 +06:00
										 |  |  | static void remap_hooks_and_vertex_parents(Object *obedit) | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | { | 
					
						
							|  |  |  | 	Object *object; | 
					
						
							|  |  |  | 	Curve *curve = (Curve *) obedit->data; | 
					
						
							| 
									
										
										
										
											2014-08-15 12:50:21 +06:00
										 |  |  | 	EditNurb *editnurb = curve->editnurb; | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 	int *old_to_new_map = NULL; | 
					
						
							|  |  |  | 	int old_totvert; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 12:50:21 +06:00
										 |  |  | 	if (editnurb->keyindex == NULL) { | 
					
						
							|  |  |  | 		/* TODO(sergey): Happens when separating curves, this would lead to
 | 
					
						
							|  |  |  | 		 * the wrong indices in the hook modifier, address this together with | 
					
						
							|  |  |  | 		 * other indices issues. | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 	for (object = G.main->object.first; object; object = object->id.next) { | 
					
						
							|  |  |  | 		ModifierData *md; | 
					
						
							|  |  |  | 		int index; | 
					
						
							|  |  |  | 		if ((object->parent) && | 
					
						
							|  |  |  | 		    (object->parent->data == curve) && | 
					
						
							|  |  |  | 		    ELEM(object->partype, PARVERT1, PARVERT3)) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (old_to_new_map == NULL) { | 
					
						
							| 
									
										
										
										
											2014-08-01 10:56:20 +06:00
										 |  |  | 				old_to_new_map = initialize_index_map(obedit, &old_totvert); | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (object->par1 < old_totvert) { | 
					
						
							|  |  |  | 				index = old_to_new_map[object->par1]; | 
					
						
							|  |  |  | 				if (index != -1) { | 
					
						
							|  |  |  | 					object->par1 = index; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (object->par2 < old_totvert) { | 
					
						
							|  |  |  | 				index = old_to_new_map[object->par2]; | 
					
						
							|  |  |  | 				if (index != -1) { | 
					
						
							|  |  |  | 					object->par2 = index; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (object->par3 < old_totvert) { | 
					
						
							|  |  |  | 				index = old_to_new_map[object->par3]; | 
					
						
							|  |  |  | 				if (index != -1) { | 
					
						
							|  |  |  | 					object->par3 = index; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (object->data == curve) { | 
					
						
							|  |  |  | 			for (md = object->modifiers.first; md; md = md->next) { | 
					
						
							|  |  |  | 				if (md->type == eModifierType_Hook) { | 
					
						
							|  |  |  | 					HookModifierData *hmd = (HookModifierData *) md; | 
					
						
							|  |  |  | 					int i, j; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (old_to_new_map == NULL) { | 
					
						
							| 
									
										
										
										
											2014-08-01 10:56:20 +06:00
										 |  |  | 						old_to_new_map = initialize_index_map(obedit, &old_totvert); | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					for (i = j = 0; i < hmd->totindex; i++) { | 
					
						
							|  |  |  | 						if (hmd->indexar[i] < old_totvert) { | 
					
						
							|  |  |  | 							index = old_to_new_map[hmd->indexar[i]]; | 
					
						
							|  |  |  | 							if (index != -1) { | 
					
						
							|  |  |  | 								hmd->indexar[j++] = index; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						else { | 
					
						
							|  |  |  | 							j++; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					hmd->totindex = j; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (old_to_new_map != NULL) { | 
					
						
							|  |  |  | 		MEM_freeN(old_to_new_map); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | /* load editNurb in object */ | 
					
						
							| 
									
										
										
										
											2015-11-18 12:20:28 +11:00
										 |  |  | void ED_curve_editnurb_load(Object *obedit) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	if (obedit == NULL) return; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		Curve *cu = obedit->data; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		Nurb *nu, *newnu; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		ListBase newnurb = {NULL, NULL}, oldnurb = cu->nurb; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 10:56:20 +06:00
										 |  |  | 		remap_hooks_and_vertex_parents(obedit); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							|  |  |  | 			newnu = BKE_nurb_duplicate(nu); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			BLI_addtail(&newnurb, newnu); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (nu->type == CU_NURBS) { | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 				BKE_nurb_order_clamp_u(nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		cu->nurb = newnurb; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		calc_shapeKeys(obedit); | 
					
						
							| 
									
										
										
										
											2012-04-16 08:04:12 +00:00
										 |  |  | 		ED_curve_updateAnimPaths(obedit->data); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 		BKE_nurbList_free(&oldnurb); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* make copy in cu->editnurb */ | 
					
						
							| 
									
										
										
										
											2015-11-18 12:20:28 +11:00
										 |  |  | void ED_curve_editnurb_make(Object *obedit) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Curve *cu = (Curve *)obedit->data; | 
					
						
							|  |  |  | 	EditNurb *editnurb = cu->editnurb; | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 	Nurb *nu, *newnu; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	KeyBlock *actkey; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { | 
					
						
							| 
									
										
										
										
											2012-09-19 10:12:07 +00:00
										 |  |  | 		actkey = BKE_keyblock_from_object(obedit); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (actkey) { | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			// XXX strcpy(G.editModeTitleExtra, "(Key) ");
 | 
					
						
							|  |  |  | 			undo_editmode_clear(); | 
					
						
							| 
									
										
										
										
											2014-11-16 19:15:23 +01:00
										 |  |  | 			BKE_keyblock_convert_to_curve(actkey, cu, &cu->nurb); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (editnurb) { | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 			BKE_nurbList_free(&editnurb->nurbs); | 
					
						
							|  |  |  | 			BKE_curve_editNurb_keyIndex_free(editnurb); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			editnurb->keyindex = NULL; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			editnurb = MEM_callocN(sizeof(EditNurb), "editnurb"); | 
					
						
							|  |  |  | 			cu->editnurb = editnurb; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		nu = cu->nurb.first; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		while (nu) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			newnu = BKE_nurb_duplicate(nu); | 
					
						
							|  |  |  | 			BKE_nurb_test2D(newnu); // after join, or any other creation of curve
 | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			BLI_addtail(&editnurb->nurbs, newnu); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			nu = nu->next; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (actkey) | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			editnurb->shapenr = obedit->shapenr; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:46:24 +06:00
										 |  |  | 		/* animation could be added in editmode even if there was no animdata in
 | 
					
						
							| 
									
										
										
										
											2012-03-03 16:31:46 +00:00
										 |  |  | 		 * object mode hence we always need CVs index be created */ | 
					
						
							| 
									
										
										
										
											2011-02-03 17:03:37 +00:00
										 |  |  | 		init_editNurb_keyIndex(editnurb, &cu->nurb); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-18 12:20:28 +11:00
										 |  |  | void ED_curve_editnurb_free(Object *obedit) | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Curve *cu = obedit->data; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 	BKE_curve_editNurb_free(cu); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | /******************** separate operator ***********************/ | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static int separate_exec(bContext *C, wmOperator *op) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Main *bmain = CTX_data_main(C); | 
					
						
							|  |  |  | 	Scene *scene = CTX_data_scene(C); | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 	Object *oldob, *newob; | 
					
						
							|  |  |  | 	Base *oldbase, *newbase; | 
					
						
							|  |  |  | 	Curve *oldcu, *newcu; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	EditNurb *newedit; | 
					
						
							|  |  |  | 	ListBase newnurb = {NULL, NULL}; | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	oldbase = CTX_data_active_base(C); | 
					
						
							|  |  |  | 	oldob = oldbase->object; | 
					
						
							|  |  |  | 	oldcu = oldob->data; | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (oldcu->key) { | 
					
						
							| 
									
										
										
										
											2012-10-26 17:32:50 +00:00
										 |  |  | 		BKE_report(op->reports, RPT_ERROR, "Cannot separate a curve with vertex keys"); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	WM_cursor_wait(1); | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* 1. duplicate geometry and check for valid selection for separate */ | 
					
						
							|  |  |  | 	adduplicateflagNurb(oldob, &newnurb, SELECT, true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-08 06:07:10 +11:00
										 |  |  | 	if (BLI_listbase_is_empty(&newnurb)) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 		WM_cursor_wait(0); | 
					
						
							|  |  |  | 		BKE_report(op->reports, RPT_ERROR, "Cannot separate current selection"); | 
					
						
							|  |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* 2. duplicate the object and data */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	newbase = ED_object_add_duplicate(bmain, scene, oldbase, 0); /* 0 = fully linked */ | 
					
						
							| 
									
										
										
										
											2013-02-21 19:33:04 +00:00
										 |  |  | 	DAG_relations_tag_update(bmain); | 
					
						
							| 
									
										
										
										
											2012-07-19 10:23:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	newob = newbase->object; | 
					
						
							|  |  |  | 	newcu = newob->data = BKE_curve_copy(oldcu); | 
					
						
							|  |  |  | 	newcu->editnurb = NULL; | 
					
						
							| 
									
										
										
										
											2015-11-09 19:47:10 +01:00
										 |  |  | 	id_us_min(&oldcu->id); /* because new curve is a copy: reduce user count */ | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	/* 3. put new object in editmode, clear it and set separated nurbs */ | 
					
						
							| 
									
										
										
										
											2015-11-18 12:20:28 +11:00
										 |  |  | 	ED_curve_editnurb_make(newob); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	newedit = newcu->editnurb; | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 	BKE_nurbList_free(&newedit->nurbs); | 
					
						
							|  |  |  | 	BKE_curve_editNurb_keyIndex_free(newedit); | 
					
						
							| 
									
										
										
										
											2013-05-27 10:08:56 +00:00
										 |  |  | 	newedit->keyindex = NULL; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	BLI_movelisttolist(&newedit->nurbs, &newnurb); | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	/* 4. put old object out of editmode and delete separated geometry */ | 
					
						
							| 
									
										
										
										
											2015-11-18 12:20:28 +11:00
										 |  |  | 	ED_curve_editnurb_load(newob); | 
					
						
							|  |  |  | 	ED_curve_editnurb_free(newob); | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	curve_delete_segments(oldob, true); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	DAG_id_tag_update(&oldob->id, OB_RECALC_DATA);  /* this is the original one */ | 
					
						
							|  |  |  | 	DAG_id_tag_update(&newob->id, OB_RECALC_DATA);  /* this is the separated one */ | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, oldob->data); | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, newob); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 	WM_cursor_wait(0); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | void CURVE_OT_separate(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Separate"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_separate"; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	ot->description = "Separate selected points from connected unselected points into a new object"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2015-05-27 09:53:03 +10:00
										 |  |  | 	ot->invoke = WM_operator_confirm; | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = separate_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | /******************** split operator ***********************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int curve_split_exec(bContext *C, wmOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							|  |  |  | 	ListBase newnurb = {NULL, NULL}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	adduplicateflagNurb(obedit, &newnurb, SELECT, true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-08 06:07:10 +11:00
										 |  |  | 	if (BLI_listbase_is_empty(&newnurb) == false) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 		curve_delete_segments(obedit, true); | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 		BLI_movelisttolist(editnurb, &newnurb); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (ED_curve_updateAnimPaths(obedit->data)) | 
					
						
							|  |  |  | 			WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							|  |  |  | 		DAG_id_tag_update(obedit->data, 0); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		BKE_report(op->reports, RPT_ERROR, "Cannot split current selection"); | 
					
						
							|  |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CURVE_OT_split(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							|  |  |  | 	ot->name = "Split"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_split"; | 
					
						
							|  |  |  | 	ot->description = "Split off selected points from connected unselected points"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							|  |  |  | 	ot->exec = curve_split_exec; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							|  |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | /* ******************* FLAGS ********************* */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | static short isNurbselUV(Nurb *nu, int *u, int *v, int flag) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-08-04 12:30:16 +00:00
										 |  |  | 	/* return (u != -1): 1 row in u-direction selected. U has value between 0-pntsv
 | 
					
						
							|  |  |  | 	 * return (v != -1): 1 column in v-direction selected. V has value between 0-pntsu | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	BPoint *bp; | 
					
						
							|  |  |  | 	int a, b, sel; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	*u = *v = -1; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	bp = nu->bp; | 
					
						
							|  |  |  | 	for (b = 0; b < nu->pntsv; b++) { | 
					
						
							|  |  |  | 		sel = 0; | 
					
						
							|  |  |  | 		for (a = 0; a < nu->pntsu; a++, bp++) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (bp->f1 & flag) sel++; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		if (sel == nu->pntsu) { | 
					
						
							|  |  |  | 			if (*u == -1) *u = b; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			else return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 		else if (sel > 1) { | 
					
						
							|  |  |  | 			return 0;  /* because sel == 1 is still ok */ | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (a = 0; a < nu->pntsu; a++) { | 
					
						
							|  |  |  | 		sel = 0; | 
					
						
							|  |  |  | 		bp = &nu->bp[a]; | 
					
						
							|  |  |  | 		for (b = 0; b < nu->pntsv; b++, bp += nu->pntsu) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (bp->f1 & flag) sel++; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		if (sel == nu->pntsv) { | 
					
						
							|  |  |  | 			if (*v == -1) *v = a; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			else return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 		else if (sel > 1) { | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	if (*u == -1 && *v > -1) return 1; | 
					
						
							|  |  |  | 	if (*v == -1 && *u > -1) return 1; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | /* return true if U direction is selected and number of selected columns v */ | 
					
						
							|  |  |  | static bool isNurbselU(Nurb *nu, int *v, int flag) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							|  |  |  | 	int a, b, sel; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*v = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (b = 0, bp = nu->bp; b < nu->pntsv; b++) { | 
					
						
							|  |  |  | 		sel = 0; | 
					
						
							|  |  |  | 		for (a = 0; a < nu->pntsu; a++, bp++) { | 
					
						
							|  |  |  | 			if (bp->f1 & flag) sel++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (sel == nu->pntsu) { | 
					
						
							|  |  |  | 			(*v)++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (sel >= 1) { | 
					
						
							|  |  |  | 			*v = 0; | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* return true if V direction is selected and number of selected rows u */ | 
					
						
							|  |  |  | static bool isNurbselV(Nurb *nu, int *u, int flag) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							|  |  |  | 	int a, b, sel; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*u = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (a = 0; a < nu->pntsu; a++) { | 
					
						
							|  |  |  | 		bp = &nu->bp[a]; | 
					
						
							|  |  |  | 		sel = 0; | 
					
						
							|  |  |  | 		for (b = 0; b < nu->pntsv; b++, bp += nu->pntsu) { | 
					
						
							|  |  |  | 			if (bp->f1 & flag) sel++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (sel == nu->pntsv) { | 
					
						
							|  |  |  | 			(*u)++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (sel >= 1) { | 
					
						
							|  |  |  | 			*u = 0; | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-16 00:03:33 +00:00
										 |  |  | static void rotateflagNurb(ListBase *editnurb, short flag, const float cent[3], float rotmat[3][3]) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* all verts with (flag & 'flag') rotate */ | 
					
						
							|  |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (nu->type == CU_NURBS) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			bp = nu->bp; | 
					
						
							|  |  |  | 			a = nu->pntsu * nu->pntsv; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							|  |  |  | 				if (bp->f1 & flag) { | 
					
						
							| 
									
										
										
										
											2010-09-30 05:26:36 +00:00
										 |  |  | 					sub_v3_v3(bp->vec, cent); | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | 					mul_m3_v3(rotmat, bp->vec); | 
					
						
							| 
									
										
										
										
											2010-09-30 05:26:36 +00:00
										 |  |  | 					add_v3_v3(bp->vec, cent); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				bp++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-16 00:03:33 +00:00
										 |  |  | void ed_editnurb_translate_flag(ListBase *editnurb, short flag, const float vec[3]) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* all verts with ('flag' & flag) translate */ | 
					
						
							|  |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	BezTriple *bezt; | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (nu->type == CU_BEZIER) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			a = nu->pntsu; | 
					
						
							|  |  |  | 			bezt = nu->bezt; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							|  |  |  | 				if (bezt->f1 & flag) add_v3_v3(bezt->vec[0], vec); | 
					
						
							|  |  |  | 				if (bezt->f2 & flag) add_v3_v3(bezt->vec[1], vec); | 
					
						
							|  |  |  | 				if (bezt->f3 & flag) add_v3_v3(bezt->vec[2], vec); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				bezt++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			a = nu->pntsu * nu->pntsv; | 
					
						
							|  |  |  | 			bp = nu->bp; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							|  |  |  | 				if (bp->f1 & flag) add_v3_v3(bp->vec, vec); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				bp++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 		BKE_nurb_test2D(nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-30 05:26:36 +00:00
										 |  |  | static void weightflagNurb(ListBase *editnurb, short flag, float w) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (nu->type == CU_NURBS) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			a = nu->pntsu * nu->pntsv; | 
					
						
							|  |  |  | 			bp = nu->bp; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							|  |  |  | 				if (bp->f1 & flag) { | 
					
						
							| 
									
										
										
										
											2010-09-30 05:26:36 +00:00
										 |  |  | 					/* a mode used to exist for replace/multiple but is was unused */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bp->vec[3] *= w; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				bp++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | static void ed_surf_delete_selected(Object *obedit) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Curve *cu = obedit->data; | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu, *next; | 
					
						
							|  |  |  | 	BPoint *bp, *bpn, *newbp; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	int a, b, newu, newv; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-21 15:03:34 +11:00
										 |  |  | 	BLI_assert(obedit->type == OB_SURF); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	nu = editnurb->first; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (nu) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		next = nu->next; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* is entire nurb selected */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		bp = nu->bp; | 
					
						
							|  |  |  | 		a = nu->pntsu * nu->pntsv; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		while (a) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			a--; | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 			if (bp->f1 & SELECT) { | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 				/* pass */ | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			bp++; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		if (a == 0) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			BLI_remlink(editnurb, nu); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			keyIndex_delNurb(cu->editnurb, nu); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			BKE_nurb_free(nu); nu = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 			if (isNurbselU(nu, &newv, SELECT)) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 				/* U direction selected */ | 
					
						
							|  |  |  | 				newv = nu->pntsv - newv; | 
					
						
							|  |  |  | 				if (newv != nu->pntsv) { | 
					
						
							|  |  |  | 					/* delete */ | 
					
						
							|  |  |  | 					bp = nu->bp; | 
					
						
							|  |  |  | 					bpn = newbp = (BPoint *)MEM_mallocN(newv * nu->pntsu * sizeof(BPoint), "deleteNurb"); | 
					
						
							|  |  |  | 					for (b = 0; b < nu->pntsv; b++) { | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 						if ((bp->f1 & SELECT) == 0) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							memcpy(bpn, bp, nu->pntsu * sizeof(BPoint)); | 
					
						
							|  |  |  | 							keyIndex_updateBP(cu->editnurb, bp, bpn, nu->pntsu); | 
					
						
							|  |  |  | 							bpn += nu->pntsu; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						else { | 
					
						
							|  |  |  | 							keyIndex_delBP(cu->editnurb, bp); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						bp += nu->pntsu; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					nu->pntsv = newv; | 
					
						
							|  |  |  | 					MEM_freeN(nu->bp); | 
					
						
							|  |  |  | 					nu->bp = newbp; | 
					
						
							|  |  |  | 					BKE_nurb_order_clamp_v(nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					BKE_nurb_knot_calc_v(nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 			else if (isNurbselV(nu, &newu, SELECT)) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 				/* V direction selected */ | 
					
						
							|  |  |  | 				newu = nu->pntsu - newu; | 
					
						
							|  |  |  | 				if (newu != nu->pntsu) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					/* delete */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bp = nu->bp; | 
					
						
							|  |  |  | 					bpn = newbp = (BPoint *)MEM_mallocN(newu * nu->pntsv * sizeof(BPoint), "deleteNurb"); | 
					
						
							|  |  |  | 					for (b = 0; b < nu->pntsv; b++) { | 
					
						
							|  |  |  | 						for (a = 0; a < nu->pntsu; a++, bp++) { | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 							if ((bp->f1 & SELECT) == 0) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 								*bpn = *bp; | 
					
						
							| 
									
										
										
										
											2010-12-06 21:18:08 +00:00
										 |  |  | 								keyIndex_updateBP(cu->editnurb, bp, bpn, 1); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 								bpn++; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 							} | 
					
						
							|  |  |  | 							else { | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 								keyIndex_delBP(cu->editnurb, bp); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					MEM_freeN(nu->bp); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					nu->bp = newbp; | 
					
						
							|  |  |  | 					if (newu == 1 && nu->pntsv > 1) {    /* make a U spline */ | 
					
						
							|  |  |  | 						nu->pntsu = nu->pntsv; | 
					
						
							|  |  |  | 						nu->pntsv = 1; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						SWAP(short, nu->orderu, nu->orderv); | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 						BKE_nurb_order_clamp_u(nu); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 						if (nu->knotsv) MEM_freeN(nu->knotsv); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						nu->knotsv = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						nu->pntsu = newu; | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 						BKE_nurb_order_clamp_u(nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 					BKE_nurb_knot_calc_u(nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		nu = next; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | static void ed_curve_delete_selected(Object *obedit) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Curve *cu = obedit->data; | 
					
						
							|  |  |  | 	EditNurb *editnurb = cu->editnurb; | 
					
						
							|  |  |  | 	ListBase *nubase = &editnurb->nurbs; | 
					
						
							|  |  |  | 	Nurb *nu, *next; | 
					
						
							|  |  |  | 	BezTriple *bezt, *bezt1; | 
					
						
							|  |  |  | 	BPoint *bp, *bp1; | 
					
						
							|  |  |  | 	int a, type, nuindex = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* first loop, can we remove entire pieces? */ | 
					
						
							|  |  |  | 	nu = nubase->first; | 
					
						
							|  |  |  | 	while (nu) { | 
					
						
							|  |  |  | 		next = nu->next; | 
					
						
							|  |  |  | 		if (nu->type == CU_BEZIER) { | 
					
						
							|  |  |  | 			bezt = nu->bezt; | 
					
						
							|  |  |  | 			a = nu->pntsu; | 
					
						
							|  |  |  | 			if (a) { | 
					
						
							|  |  |  | 				while (a) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 					if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt)) { | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 						/* pass */ | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					a--; | 
					
						
							|  |  |  | 					bezt++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (a == 0) { | 
					
						
							|  |  |  | 					if (cu->actnu == nuindex) | 
					
						
							| 
									
										
										
										
											2014-05-26 09:17:00 +10:00
										 |  |  | 						cu->actnu = CU_ACT_NONE; | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					BLI_remlink(nubase, nu); | 
					
						
							|  |  |  | 					keyIndex_delNurb(editnurb, nu); | 
					
						
							|  |  |  | 					BKE_nurb_free(nu); nu = NULL; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			bp = nu->bp; | 
					
						
							|  |  |  | 			a = nu->pntsu * nu->pntsv; | 
					
						
							|  |  |  | 			if (a) { | 
					
						
							|  |  |  | 				while (a) { | 
					
						
							|  |  |  | 					if (bp->f1 & SELECT) { | 
					
						
							|  |  |  | 						/* pass */ | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					a--; | 
					
						
							|  |  |  | 					bp++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (a == 0) { | 
					
						
							|  |  |  | 					if (cu->actnu == nuindex) | 
					
						
							| 
									
										
										
										
											2014-05-26 09:17:00 +10:00
										 |  |  | 						cu->actnu = CU_ACT_NONE; | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					BLI_remlink(nubase, nu); | 
					
						
							|  |  |  | 					keyIndex_delNurb(editnurb, nu); | 
					
						
							|  |  |  | 					BKE_nurb_free(nu); nu = NULL; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Never allow the order to exceed the number of points
 | 
					
						
							|  |  |  | 		 * - note, this is ok but changes unselected nurbs, disable for now */ | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | 		if ((nu != NULL) && (nu->type == CU_NURBS)) { | 
					
						
							|  |  |  | 			clamp_nurb_order_u(nu); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 		nu = next; | 
					
						
							|  |  |  | 		nuindex++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* 2nd loop, delete small pieces: just for curves */ | 
					
						
							|  |  |  | 	nu = nubase->first; | 
					
						
							|  |  |  | 	while (nu) { | 
					
						
							|  |  |  | 		next = nu->next; | 
					
						
							|  |  |  | 		type = 0; | 
					
						
							|  |  |  | 		if (nu->type == CU_BEZIER) { | 
					
						
							|  |  |  | 			bezt = nu->bezt; | 
					
						
							|  |  |  | 			for (a = 0; a < nu->pntsu; a++) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt)) { | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 					memmove(bezt, bezt + 1, (nu->pntsu - a - 1) * sizeof(BezTriple)); | 
					
						
							| 
									
										
										
										
											2014-07-18 13:38:09 +06:00
										 |  |  | 					keyIndex_delBezt(editnurb, bezt); | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 					keyIndex_updateBezt(editnurb, bezt + 1, bezt, nu->pntsu - a - 1); | 
					
						
							|  |  |  | 					nu->pntsu--; | 
					
						
							|  |  |  | 					a--; | 
					
						
							|  |  |  | 					type = 1; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					bezt++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (type) { | 
					
						
							|  |  |  | 				bezt1 = (BezTriple *)MEM_mallocN((nu->pntsu) * sizeof(BezTriple), "delNurb"); | 
					
						
							|  |  |  | 				memcpy(bezt1, nu->bezt, (nu->pntsu) * sizeof(BezTriple)); | 
					
						
							|  |  |  | 				keyIndex_updateBezt(editnurb, nu->bezt, bezt1, nu->pntsu); | 
					
						
							|  |  |  | 				MEM_freeN(nu->bezt); | 
					
						
							|  |  |  | 				nu->bezt = bezt1; | 
					
						
							|  |  |  | 				BKE_nurb_handles_calc(nu); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (nu->pntsv == 1) { | 
					
						
							|  |  |  | 			bp = nu->bp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (a = 0; a < nu->pntsu; a++) { | 
					
						
							|  |  |  | 				if (bp->f1 & SELECT) { | 
					
						
							|  |  |  | 					memmove(bp, bp + 1, (nu->pntsu - a - 1) * sizeof(BPoint)); | 
					
						
							| 
									
										
										
										
											2014-07-18 13:38:09 +06:00
										 |  |  | 					keyIndex_delBP(editnurb, bp); | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 					keyIndex_updateBP(editnurb, bp + 1, bp, nu->pntsu - a - 1); | 
					
						
							|  |  |  | 					nu->pntsu--; | 
					
						
							|  |  |  | 					a--; | 
					
						
							|  |  |  | 					type = 1; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					bp++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (type) { | 
					
						
							|  |  |  | 				bp1 = (BPoint *)MEM_mallocN(nu->pntsu * sizeof(BPoint), "delNurb2"); | 
					
						
							|  |  |  | 				memcpy(bp1, nu->bp, (nu->pntsu) * sizeof(BPoint)); | 
					
						
							|  |  |  | 				keyIndex_updateBP(editnurb, nu->bp, bp1, nu->pntsu); | 
					
						
							|  |  |  | 				MEM_freeN(nu->bp); | 
					
						
							|  |  |  | 				nu->bp = bp1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Never allow the order to exceed the number of points
 | 
					
						
							|  |  |  | 				 * - note, this is ok but changes unselected nurbs, disable for now */ | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | 				if (nu->type == CU_NURBS) { | 
					
						
							|  |  |  | 					clamp_nurb_order_u(nu); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			BKE_nurb_order_clamp_u(nu); | 
					
						
							|  |  |  | 			BKE_nurb_knot_calc_u(nu); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		nu = next; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* only for OB_SURF */ | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | bool ed_editnurb_extrude_flag(EditNurb *editnurb, const short flag) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	BPoint *bp, *bpn, *newbp; | 
					
						
							| 
									
										
										
										
											2013-09-16 00:03:33 +00:00
										 |  |  | 	int a, u, v, len; | 
					
						
							|  |  |  | 	bool ok = false; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	nu = editnurb->nurbs.first; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (nu) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		if (nu->pntsv == 1) { | 
					
						
							|  |  |  | 			bp = nu->bp; | 
					
						
							|  |  |  | 			a = nu->pntsu; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a) { | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 				if (bp->f1 & flag) { | 
					
						
							|  |  |  | 					/* pass */ | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				bp++; | 
					
						
							|  |  |  | 				a--; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			if (a == 0) { | 
					
						
							| 
									
										
										
										
											2013-09-16 00:03:33 +00:00
										 |  |  | 				ok = true; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				newbp = (BPoint *)MEM_mallocN(2 * nu->pntsu * sizeof(BPoint), "extrudeNurb1"); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				ED_curve_bpcpy(editnurb, newbp, nu->bp, nu->pntsu); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				bp = newbp + nu->pntsu; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				ED_curve_bpcpy(editnurb, bp, nu->bp, nu->pntsu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				MEM_freeN(nu->bp); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				nu->bp = newbp; | 
					
						
							|  |  |  | 				a = nu->pntsu; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				while (a--) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					select_bpoint(bp, SELECT, flag, HIDDEN); | 
					
						
							|  |  |  | 					select_bpoint(newbp, DESELECT, flag, HIDDEN); | 
					
						
							|  |  |  | 					bp++;  | 
					
						
							|  |  |  | 					newbp++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				nu->pntsv = 2; | 
					
						
							|  |  |  | 				nu->orderv = 2; | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 				BKE_nurb_knot_calc_v(nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			/* which row or column is selected */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 			if (isNurbselUV(nu, &u, &v, flag)) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* deselect all */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				bp = nu->bp; | 
					
						
							|  |  |  | 				a = nu->pntsu * nu->pntsv; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				while (a--) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					select_bpoint(bp, DESELECT, flag, HIDDEN); | 
					
						
							|  |  |  | 					bp++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				if (u == 0 || u == nu->pntsv - 1) {      /* row in u-direction selected */ | 
					
						
							| 
									
										
										
										
											2013-09-16 00:03:33 +00:00
										 |  |  | 					ok = true; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					newbp = (BPoint *)MEM_mallocN(nu->pntsu * (nu->pntsv + 1) * | 
					
						
							|  |  |  | 					                              sizeof(BPoint), "extrudeNurb1"); | 
					
						
							|  |  |  | 					if (u == 0) { | 
					
						
							|  |  |  | 						len = nu->pntsv * nu->pntsu; | 
					
						
							|  |  |  | 						ED_curve_bpcpy(editnurb, newbp + nu->pntsu, nu->bp, len); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 						ED_curve_bpcpy(editnurb, newbp, nu->bp, nu->pntsu); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						bp = newbp; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						len = nu->pntsv * nu->pntsu; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 						ED_curve_bpcpy(editnurb, newbp, nu->bp, len); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						ED_curve_bpcpy(editnurb, newbp + len, &nu->bp[len - nu->pntsu], nu->pntsu); | 
					
						
							|  |  |  | 						bp = newbp + len; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					a = nu->pntsu; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					while (a--) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						select_bpoint(bp, SELECT, flag, HIDDEN); | 
					
						
							|  |  |  | 						bp++; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					MEM_freeN(nu->bp); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					nu->bp = newbp; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					nu->pntsv++; | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 					BKE_nurb_knot_calc_v(nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				else if (v == 0 || v == nu->pntsu - 1) {     /* column in v-direction selected */ | 
					
						
							| 
									
										
										
										
											2013-09-16 00:03:33 +00:00
										 |  |  | 					ok = true; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bpn = newbp = (BPoint *)MEM_mallocN((nu->pntsu + 1) * nu->pntsv * sizeof(BPoint), "extrudeNurb1"); | 
					
						
							|  |  |  | 					bp = nu->bp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					for (a = 0; a < nu->pntsv; a++) { | 
					
						
							|  |  |  | 						if (v == 0) { | 
					
						
							|  |  |  | 							*bpn = *bp; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 							bpn->f1 |= flag; | 
					
						
							|  |  |  | 							bpn++; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 						ED_curve_bpcpy(editnurb, bpn, bp, nu->pntsu); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						bp += nu->pntsu; | 
					
						
							|  |  |  | 						bpn += nu->pntsu; | 
					
						
							|  |  |  | 						if (v == nu->pntsu - 1) { | 
					
						
							|  |  |  | 							*bpn = *(bp - 1); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 							bpn->f1 |= flag; | 
					
						
							|  |  |  | 							bpn++; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					MEM_freeN(nu->bp); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					nu->bp = newbp; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					nu->pntsu++; | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 					BKE_nurb_knot_calc_u(nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		nu = nu->next; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ok; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | static void adduplicateflagNurb(Object *obedit, ListBase *newnurb, | 
					
						
							|  |  |  |                                 const short flag, const bool split) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	Nurb *nu = editnurb->last, *newnu; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	BezTriple *bezt, *bezt1; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	BPoint *bp, *bp1, *bp2, *bp3; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Curve *cu = (Curve *)obedit->data; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	int a, b, c, starta, enda, diffa, cyclicu, cyclicv, newu, newv; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	char *usel; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (nu) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 		cyclicu = cyclicv = 0; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (nu->type == CU_BEZIER) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 			for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				enda = -1; | 
					
						
							|  |  |  | 				starta = a; | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 				while ((bezt->f1 & flag) || (bezt->f2 & flag) || (bezt->f3 & flag)) { | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 					if (!split) select_beztriple(bezt, DESELECT, flag, HIDDEN); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					enda = a; | 
					
						
							|  |  |  | 					if (a >= nu->pntsu - 1) break; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					a++; | 
					
						
							|  |  |  | 					bezt++; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				if (enda >= starta) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					newu = diffa = enda - starta + 1; /* set newu and diffa, may use both */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (starta == 0 && newu != nu->pntsu && (nu->flagu & CU_NURB_CYCLIC)) { | 
					
						
							|  |  |  | 						cyclicu = newu; | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						if (enda == nu->pntsu - 1) newu += cyclicu; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						newnu = BKE_nurb_copy(nu, newu, 1); | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 						BLI_addtail(newnurb, newnu); | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						memcpy(newnu->bezt, &nu->bezt[starta], diffa * sizeof(BezTriple)); | 
					
						
							|  |  |  | 						if (newu != diffa) { | 
					
						
							|  |  |  | 							memcpy(&newnu->bezt[diffa], nu->bezt, cyclicu * sizeof(BezTriple)); | 
					
						
							|  |  |  | 							cyclicu = 0; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						if (newu != nu->pntsu) newnu->flagu &= ~CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						for (b = 0, bezt1 = newnu->bezt; b < newnu->pntsu; b++, bezt1++) { | 
					
						
							|  |  |  | 							select_beztriple(bezt1, SELECT, flag, HIDDEN); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (cyclicu != 0) { | 
					
						
							|  |  |  | 				newnu = BKE_nurb_copy(nu, cyclicu, 1); | 
					
						
							|  |  |  | 				BLI_addtail(newnurb, newnu); | 
					
						
							|  |  |  | 				memcpy(newnu->bezt, nu->bezt, cyclicu * sizeof(BezTriple)); | 
					
						
							|  |  |  | 				newnu->flagu &= ~CU_NURB_CYCLIC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				for (b = 0, bezt1 = newnu->bezt; b < newnu->pntsu; b++, bezt1++) { | 
					
						
							|  |  |  | 					select_beztriple(bezt1, SELECT, flag, HIDDEN); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		else if (nu->pntsv == 1) {    /* because UV Nurb has a different method for dupli */ | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 			for (a = 0, bp = nu->bp; a < nu->pntsu; a++, bp++) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				enda = -1; | 
					
						
							|  |  |  | 				starta = a; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				while (bp->f1 & flag) { | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 					if (!split) select_bpoint(bp, DESELECT, flag, HIDDEN); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					enda = a; | 
					
						
							|  |  |  | 					if (a >= nu->pntsu - 1) break; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					a++; | 
					
						
							|  |  |  | 					bp++; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				if (enda >= starta) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					newu = diffa = enda - starta + 1; /* set newu and diffa, may use both */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (starta == 0 && newu != nu->pntsu && (nu->flagu & CU_NURB_CYCLIC)) { | 
					
						
							|  |  |  | 						cyclicu = newu; | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						if (enda == nu->pntsu - 1) newu += cyclicu; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						newnu = BKE_nurb_copy(nu, newu, 1); | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 						BLI_addtail(newnurb, newnu); | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						memcpy(newnu->bp, &nu->bp[starta], diffa * sizeof(BPoint)); | 
					
						
							|  |  |  | 						if (newu != diffa) { | 
					
						
							|  |  |  | 							memcpy(&newnu->bp[diffa], nu->bp, cyclicu * sizeof(BPoint)); | 
					
						
							|  |  |  | 							cyclicu = 0; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						if (newu != nu->pntsu) newnu->flagu &= ~CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						for (b = 0, bp1 = newnu->bp; b < newnu->pntsu; b++, bp1++) { | 
					
						
							|  |  |  | 							select_bpoint(bp1, SELECT, flag, HIDDEN); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (cyclicu != 0) { | 
					
						
							|  |  |  | 				newnu = BKE_nurb_copy(nu, cyclicu, 1); | 
					
						
							|  |  |  | 				BLI_addtail(newnurb, newnu); | 
					
						
							|  |  |  | 				memcpy(newnu->bp, nu->bp, cyclicu * sizeof(BPoint)); | 
					
						
							|  |  |  | 				newnu->flagu &= ~CU_NURB_CYCLIC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				for (b = 0, bp1 = newnu->bp; b < newnu->pntsu; b++, bp1++) { | 
					
						
							|  |  |  | 					select_bpoint(bp1, SELECT, flag, HIDDEN); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 			if (ED_curve_nurb_select_check(cu, nu)) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 				/* a rectangular area in nurb has to be selected and if splitting must be in U or V direction */ | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 				usel = MEM_callocN(nu->pntsu, "adduplicateN3"); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				bp = nu->bp; | 
					
						
							|  |  |  | 				for (a = 0; a < nu->pntsv; a++) { | 
					
						
							|  |  |  | 					for (b = 0; b < nu->pntsu; b++, bp++) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 						if (bp->f1 & flag) usel[b]++; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				newu = 0; | 
					
						
							|  |  |  | 				newv = 0; | 
					
						
							|  |  |  | 				for (a = 0; a < nu->pntsu; a++) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					if (usel[a]) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						if (newv == 0 || usel[a] == newv) { | 
					
						
							|  |  |  | 							newv = usel[a]; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 							newu++; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							newv = 0; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 							break; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 				MEM_freeN(usel); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if ((newu == 0 || newv == 0) || | 
					
						
							| 
									
										
										
										
											2013-10-23 02:52:27 +00:00
										 |  |  | 				    (split && !isNurbselU(nu, &newv, SELECT) && !isNurbselV(nu, &newu, SELECT))) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2012-03-31 00:59:17 +00:00
										 |  |  | 					if (G.debug & G_DEBUG) | 
					
						
							| 
									
										
										
										
											2010-01-22 06:48:29 +00:00
										 |  |  | 						printf("Can't duplicate Nurb\n"); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					for (a = 0, bp1 = nu->bp; a < nu->pntsu * nu->pntsv; a++, bp1++) { | 
					
						
							|  |  |  | 						newv = newu = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if ((bp1->f1 & flag) && !(bp1->f1 & SURF_SEEN)) { | 
					
						
							|  |  |  | 							/* point selected, now loop over points in U and V directions */ | 
					
						
							|  |  |  | 							for (b = a % nu->pntsu, bp2 = bp1; b < nu->pntsu; b++, bp2++) { | 
					
						
							|  |  |  | 								if (bp2->f1 & flag) { | 
					
						
							|  |  |  | 									newu++; | 
					
						
							|  |  |  | 									for (c = a / nu->pntsu, bp3 = bp2; c < nu->pntsv; c++, bp3 += nu->pntsu) { | 
					
						
							|  |  |  | 										if (bp3->f1 & flag) { | 
					
						
							|  |  |  | 											bp3->f1 |= SURF_SEEN; /* flag as seen so skipped on future iterations */ | 
					
						
							|  |  |  | 											if (newu == 1) newv++; | 
					
						
							|  |  |  | 										} | 
					
						
							|  |  |  | 										else { | 
					
						
							|  |  |  | 											break; | 
					
						
							|  |  |  | 										} | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 								else { | 
					
						
							|  |  |  | 									break; | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						if ((newu + newv) > 2) { | 
					
						
							|  |  |  | 							/* ignore single points */ | 
					
						
							|  |  |  | 							if (a == 0) { | 
					
						
							|  |  |  | 								/* check if need to save cyclic selection and continue if so */ | 
					
						
							|  |  |  | 								if (newu == nu->pntsu && (nu->flagv & CU_NURB_CYCLIC)) cyclicv = newv; | 
					
						
							|  |  |  | 								if (newv == nu->pntsv && (nu->flagu & CU_NURB_CYCLIC)) cyclicu = newu; | 
					
						
							|  |  |  | 								if (cyclicu != 0 || cyclicv != 0) continue; | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							if (a + newu == nu->pntsu && cyclicu != 0) { | 
					
						
							|  |  |  | 								/* cyclic in U direction */ | 
					
						
							|  |  |  | 								newnu = BKE_nurb_copy(nu, newu + cyclicu, newv); | 
					
						
							|  |  |  | 								for (b = 0; b < newv; b++) { | 
					
						
							|  |  |  | 									memcpy(&newnu->bp[b * newnu->pntsu], &nu->bp[b * nu->pntsu + a], newu * sizeof(BPoint)); | 
					
						
							|  |  |  | 									memcpy(&newnu->bp[b * newnu->pntsu + newu], &nu->bp[b * nu->pntsu], cyclicu * sizeof(BPoint)); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 								cyclicu = cyclicv = 0; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							else if ((a / nu->pntsu) + newv == nu->pntsv && cyclicv != 0) { | 
					
						
							|  |  |  | 								/* cyclic in V direction */ | 
					
						
							|  |  |  | 								newnu = BKE_nurb_copy(nu, newu, newv + cyclicv); | 
					
						
							|  |  |  | 								memcpy(newnu->bp, &nu->bp[a], newu * newv * sizeof(BPoint)); | 
					
						
							|  |  |  | 								memcpy(&newnu->bp[newu * newv], nu->bp, newu * cyclicv * sizeof(BPoint)); | 
					
						
							|  |  |  | 								cyclicu = cyclicv = 0; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							else { | 
					
						
							|  |  |  | 								newnu = BKE_nurb_copy(nu, newu, newv); | 
					
						
							|  |  |  | 								for (b = 0; b < newv; b++) { | 
					
						
							|  |  |  | 									memcpy(&newnu->bp[b * newu], &nu->bp[b * nu->pntsu + a], newu * sizeof(BPoint)); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							BLI_addtail(newnurb, newnu); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							if (newu != nu->pntsu) newnu->flagu &= ~CU_NURB_CYCLIC; | 
					
						
							|  |  |  | 							if (newv != nu->pntsv) newnu->flagv &= ~CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					if (cyclicu != 0 || cyclicv != 0) { | 
					
						
							|  |  |  | 						/* copy start of a cyclic surface, or copying all selected points */ | 
					
						
							|  |  |  | 						newu = cyclicu == 0 ? nu->pntsu : cyclicu; | 
					
						
							|  |  |  | 						newv = cyclicv == 0 ? nu->pntsv : cyclicv; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						newnu = BKE_nurb_copy(nu, newu, newv); | 
					
						
							|  |  |  | 						for (b = 0; b < newv; b++) { | 
					
						
							|  |  |  | 							memcpy(&newnu->bp[b * newu], &nu->bp[b * nu->pntsu], newu * sizeof(BPoint)); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						BLI_addtail(newnurb, newnu); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if (newu != nu->pntsu) newnu->flagu &= ~CU_NURB_CYCLIC; | 
					
						
							|  |  |  | 						if (newv != nu->pntsv) newnu->flagv &= ~CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					for (b = 0, bp1 = nu->bp; b < nu->pntsu * nu->pntsv; b++, bp1++) { | 
					
						
							|  |  |  | 						bp1->f1 &= ~SURF_SEEN; | 
					
						
							|  |  |  | 						if (!split) select_bpoint(bp1, DESELECT, flag, HIDDEN); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		nu = nu->prev; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-08 06:07:10 +11:00
										 |  |  | 	if (BLI_listbase_is_empty(newnurb) == false) { | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 		cu->actnu = cu->actvert = CU_ACT_NONE; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-05 23:37:09 +00:00
										 |  |  | 		for (nu = newnurb->first; nu; nu = nu->next) { | 
					
						
							|  |  |  | 			if (nu->type == CU_BEZIER) { | 
					
						
							|  |  |  | 				if (split) { | 
					
						
							|  |  |  | 					/* recalc first and last */ | 
					
						
							|  |  |  | 					BKE_nurb_handle_calc_simple(nu, &nu->bezt[0]); | 
					
						
							|  |  |  | 					BKE_nurb_handle_calc_simple(nu, &nu->bezt[nu->pntsu - 1]); | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-11-05 23:37:09 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				/* knots done after duplicate as pntsu may change */ | 
					
						
							|  |  |  | 				BKE_nurb_order_clamp_u(nu); | 
					
						
							|  |  |  | 				BKE_nurb_knot_calc_u(nu); | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-05 23:37:09 +00:00
										 |  |  | 				if (obedit->type == OB_SURF) { | 
					
						
							|  |  |  | 					for (a = 0, bp = nu->bp; a < nu->pntsu * nu->pntsv; a++, bp++) { | 
					
						
							|  |  |  | 						bp->f1 &= ~SURF_SEEN; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					BKE_nurb_order_clamp_v(nu); | 
					
						
							|  |  |  | 					BKE_nurb_knot_calc_v(nu); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | /**************** switch direction operator ***************/ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-15 01:36:14 +00:00
										 |  |  | static int switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	Curve *cu = (Curve *)obedit->data; | 
					
						
							|  |  |  | 	EditNurb *editnurb = cu->editnurb; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu; | 
					
						
							| 
									
										
										
										
											2014-05-26 09:34:14 +10:00
										 |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-26 09:34:14 +10:00
										 |  |  | 	for (nu = editnurb->nurbs.first, i = 0; nu; nu = nu->next, i++) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 		if (ED_curve_nurb_select_check(cu, nu)) { | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 			BKE_nurb_direction_switch(nu); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 			keyData_switchDirectionNurb(cu, nu); | 
					
						
							| 
									
										
										
										
											2014-05-26 09:34:14 +10:00
										 |  |  | 			if ((i == cu->actnu) && (cu->actvert != CU_ACT_NONE)) { | 
					
						
							|  |  |  | 				cu->actvert = (nu->pntsu - 1) - cu->actvert; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-02-19 10:31:29 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-16 08:04:12 +00:00
										 |  |  | 	if (ED_curve_updateAnimPaths(obedit->data)) | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); | 
					
						
							| 
									
										
										
										
											2010-12-20 19:47:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | void CURVE_OT_switch_direction(wmOperatorType *ot) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Switch Direction"; | 
					
						
							|  |  |  | 	ot->description = "Switch direction of selected splines"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_switch_direction"; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = switch_direction_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | /****************** set weight operator *******************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-07 05:47:34 +00:00
										 |  |  | static int set_goal_weight_exec(bContext *C, wmOperator *op) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	BezTriple *bezt; | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	float weight = RNA_float_get(op->ptr, "weight"); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	int a; | 
					
						
							|  |  |  | 				 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (nu->bezt) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (bezt->f2 & SELECT) | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bezt->weight = weight; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		else if (nu->bp) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (bp->f1 & SELECT) | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bp->weight = weight; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-29 02:15:13 +00:00
										 |  |  | void CURVE_OT_spline_weight_set(wmOperatorType *ot) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Set Goal Weight"; | 
					
						
							|  |  |  | 	ot->description = "Set softbody goal weight for selected points"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_spline_weight_set"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = set_goal_weight_exec; | 
					
						
							|  |  |  | 	ot->invoke = WM_operator_props_popup; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* properties */ | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 	RNA_def_float_factor(ot->srna, "weight", 1.0f, 0.0f, 1.0f, "Weight", "", 0.0f, 1.0f); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /******************* set radius operator ******************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int set_radius_exec(bContext *C, wmOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	BezTriple *bezt; | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	float radius = RNA_float_get(op->ptr, "radius"); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	int a; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (nu->bezt) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (bezt->f2 & SELECT) | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bezt->radius = radius; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		else if (nu->bp) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (bp->f1 & SELECT) | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bp->radius = radius; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-29 02:15:13 +00:00
										 |  |  | void CURVE_OT_radius_set(wmOperatorType *ot) | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Set Curve Radius"; | 
					
						
							|  |  |  | 	ot->description = "Set per-point radius which is used for bevel tapering"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_radius_set"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = set_radius_exec; | 
					
						
							|  |  |  | 	ot->invoke = WM_operator_props_popup; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* properties */ | 
					
						
							| 
									
										
										
										
											2015-06-21 16:06:44 +02:00
										 |  |  | 	RNA_def_float(ot->srna, "radius", 1.0f, 0.0f, OBJECT_ADD_SIZE_MAXF, "Radius", "", 0.0001f, 10.0f); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | /********************* smooth operator ********************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-28 09:21:01 +11:00
										 |  |  | static void smooth_single_bezt( | 
					
						
							|  |  |  |         BezTriple *bezt, | 
					
						
							|  |  |  |         const BezTriple *bezt_orig_prev, const BezTriple *bezt_orig_next, | 
					
						
							|  |  |  |         float factor) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BLI_assert(IN_RANGE_INCL(factor, 0.0f, 1.0f)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < 3; i++) { | 
					
						
							|  |  |  | 		float val_old, val_new, offset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* get single dimension pos of the mid handle */ | 
					
						
							|  |  |  | 		val_old = bezt->vec[1][i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* get the weights of the previous/next mid handles and calc offset */ | 
					
						
							|  |  |  | 		val_new = (bezt_orig_prev->vec[1][i] * 0.5f) + (bezt_orig_next->vec[1][i] * 0.5f); | 
					
						
							|  |  |  | 		offset = (val_old * (1.0f - factor)) + (val_new * factor) - val_old; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* offset midpoint and 2 handles */ | 
					
						
							|  |  |  | 		bezt->vec[1][i] += offset; | 
					
						
							|  |  |  | 		bezt->vec[0][i] += offset; | 
					
						
							|  |  |  | 		bezt->vec[2][i] += offset; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Same as smooth_single_bezt(), keep in sync | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void smooth_single_bp( | 
					
						
							|  |  |  |         BPoint *bp, | 
					
						
							|  |  |  |         const BPoint *bp_orig_prev, const BPoint *bp_orig_next, | 
					
						
							|  |  |  |         float factor) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BLI_assert(IN_RANGE_INCL(factor, 0.0f, 1.0f)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < 3; i++) { | 
					
						
							|  |  |  | 		float val_old, val_new, offset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		val_old = bp->vec[i]; | 
					
						
							|  |  |  | 		val_new = (bp_orig_prev->vec[i] * 0.5f) + (bp_orig_next->vec[i] * 0.5f); | 
					
						
							|  |  |  | 		offset = (val_old * (1.0f - factor)) + (val_new * factor) - val_old; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		bp->vec[i] += offset; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-15 01:36:14 +00:00
										 |  |  | static int smooth_exec(bContext *C, wmOperator *UNUSED(op)) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-03-28 09:21:01 +11:00
										 |  |  | 	const float factor = 1.0f / 6.0f; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu; | 
					
						
							| 
									
										
										
										
											2014-03-28 09:21:01 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	int a, a_end; | 
					
						
							| 
									
										
										
										
											2013-11-26 06:39:14 +11:00
										 |  |  | 	bool changed = false; | 
					
						
							| 
									
										
										
										
											2014-03-28 09:21:01 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (nu->bezt) { | 
					
						
							| 
									
										
										
										
											2014-03-28 09:21:01 +11:00
										 |  |  | 			/* duplicate the curve to use in weight calculation */ | 
					
						
							|  |  |  | 			const BezTriple *bezt_orig = MEM_dupallocN(nu->bezt); | 
					
						
							|  |  |  | 			BezTriple *bezt; | 
					
						
							| 
									
										
										
										
											2013-11-26 06:39:14 +11:00
										 |  |  | 			changed = false; | 
					
						
							| 
									
										
										
										
											2014-03-28 09:21:01 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* check whether its cyclic or not, and set initial & final conditions */ | 
					
						
							|  |  |  | 			if (nu->flagu & CU_NURB_CYCLIC) { | 
					
						
							|  |  |  | 				a = 0; | 
					
						
							|  |  |  | 				a_end = nu->pntsu; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				a = 1; | 
					
						
							|  |  |  | 				a_end = nu->pntsu - 1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* for all the curve points */ | 
					
						
							|  |  |  | 			for (; a < a_end; a++) { | 
					
						
							|  |  |  | 				/* respect selection */ | 
					
						
							|  |  |  | 				bezt = &nu->bezt[a]; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (bezt->f2 & SELECT) { | 
					
						
							| 
									
										
										
										
											2014-03-28 09:21:01 +11:00
										 |  |  | 					const BezTriple *bezt_orig_prev, *bezt_orig_next; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					bezt_orig_prev = &bezt_orig[mod_i(a - 1, nu->pntsu)]; | 
					
						
							|  |  |  | 					bezt_orig_next = &bezt_orig[mod_i(a + 1, nu->pntsu)]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					smooth_single_bezt(bezt, bezt_orig_prev, bezt_orig_next, factor); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-26 06:39:14 +11:00
										 |  |  | 					changed = true; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-03-28 09:21:01 +11:00
										 |  |  | 			MEM_freeN((void *)bezt_orig); | 
					
						
							| 
									
										
										
										
											2013-11-26 06:39:14 +11:00
										 |  |  | 			if (changed) { | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 				BKE_nurb_handles_calc(nu); | 
					
						
							| 
									
										
										
										
											2013-11-26 06:39:14 +11:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (nu->bp) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			/* Same as above, keep these the same! */ | 
					
						
							| 
									
										
										
										
											2014-03-28 09:21:01 +11:00
										 |  |  | 			const BPoint *bp_orig = MEM_dupallocN(nu->bp); | 
					
						
							|  |  |  | 			BPoint *bp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (nu->flagu & CU_NURB_CYCLIC) { | 
					
						
							|  |  |  | 				a = 0; | 
					
						
							|  |  |  | 				a_end = nu->pntsu; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				a = 1; | 
					
						
							|  |  |  | 				a_end = nu->pntsu - 1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (; a < a_end; a++) { | 
					
						
							|  |  |  | 				bp = &nu->bp[a]; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (bp->f1 & SELECT) { | 
					
						
							| 
									
										
										
										
											2014-03-28 09:21:01 +11:00
										 |  |  | 					const BPoint *bp_orig_prev, *bp_orig_next; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					bp_orig_prev = &bp_orig[mod_i(a - 1, nu->pntsu)]; | 
					
						
							|  |  |  | 					bp_orig_next = &bp_orig[mod_i(a + 1, nu->pntsu)]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					smooth_single_bp(bp, bp_orig_prev, bp_orig_next, factor); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-03-28 09:21:01 +11:00
										 |  |  | 			MEM_freeN((void *)bp_orig); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CURVE_OT_smooth(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Smooth"; | 
					
						
							|  |  |  | 	ot->description = "Flatten angles of selected points"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_smooth"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = smooth_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /* Smooth radius/weight/tilt
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * TODO: make smoothing distance based | 
					
						
							|  |  |  |  * TODO: support cyclic curves | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | static void curve_smooth_value(ListBase *editnurb, | 
					
						
							|  |  |  |                                const int bezt_offsetof, const int bp_offset) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	BezTriple *bezt; | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							|  |  |  | 	int a; | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	/* use for smoothing */ | 
					
						
							|  |  |  | 	int last_sel; | 
					
						
							| 
									
										
										
										
											2011-01-18 01:58:19 +00:00
										 |  |  | 	int start_sel, end_sel; /* selection indices, inclusive */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	float start_rad, end_rad, fac, range; | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (nu->bezt) { | 
					
						
							| 
									
										
										
										
											2015-08-02 13:54:06 +10:00
										 |  |  | #define BEZT_VALUE(bezt) (*((float *)((char *)(bezt) + bezt_offsetof)))
 | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			for (last_sel = 0; last_sel < nu->pntsu; last_sel++) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				/* loop over selection segments of a curve, smooth each */ | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				/* Start BezTriple code, this is duplicated below for points, make sure these functions stay in sync */ | 
					
						
							| 
									
										
										
										
											2011-01-12 03:41:12 +00:00
										 |  |  | 				start_sel = -1; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				for (bezt = &nu->bezt[last_sel], a = last_sel; a < nu->pntsu; a++, bezt++) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					if (bezt->f2 & SELECT) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						start_sel = a; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-09 00:41:09 +00:00
										 |  |  | 				/* in case there are no other selected verts */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				end_sel = start_sel; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				for (bezt = &nu->bezt[start_sel + 1], a = start_sel + 1; a < nu->pntsu; a++, bezt++) { | 
					
						
							|  |  |  | 					if ((bezt->f2 & SELECT) == 0) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					end_sel = a; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				if (start_sel == -1) { | 
					
						
							|  |  |  | 					last_sel = nu->pntsu; /* next... */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					last_sel = end_sel; /* before we modify it */ | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					/* now blend between start and end sel */ | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 					start_rad = end_rad = FLT_MAX; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					if (start_sel == end_sel) { | 
					
						
							|  |  |  | 						/* simple, only 1 point selected */ | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 						if (start_sel > 0)                         start_rad = BEZT_VALUE(&nu->bezt[start_sel - 1]); | 
					
						
							|  |  |  | 						if (end_sel != -1 && end_sel < nu->pntsu)  end_rad   = BEZT_VALUE(&nu->bezt[start_sel + 1]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if      (start_rad != FLT_MAX && end_rad >= FLT_MAX) BEZT_VALUE(&nu->bezt[start_sel]) = (start_rad + end_rad) / 2.0f; | 
					
						
							|  |  |  | 						else if (start_rad != FLT_MAX)                       BEZT_VALUE(&nu->bezt[start_sel]) = start_rad; | 
					
						
							|  |  |  | 						else if (end_rad   != FLT_MAX)                       BEZT_VALUE(&nu->bezt[start_sel]) = end_rad; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						/* if endpoints selected, then use them */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						if (start_sel == 0) { | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 							start_rad = BEZT_VALUE(&nu->bezt[start_sel]); | 
					
						
							| 
									
										
										
										
											2012-03-18 07:38:51 +00:00
										 |  |  | 							start_sel++; /* we don't want to edit the selected endpoint */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						else { | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 							start_rad = BEZT_VALUE(&nu->bezt[start_sel - 1]); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						if (end_sel == nu->pntsu - 1) { | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 							end_rad = BEZT_VALUE(&nu->bezt[end_sel]); | 
					
						
							| 
									
										
										
										
											2012-03-18 07:38:51 +00:00
										 |  |  | 							end_sel--; /* we don't want to edit the selected endpoint */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						else { | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 							end_rad = BEZT_VALUE(&nu->bezt[end_sel + 1]); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						/* Now Blend between the points */ | 
					
						
							|  |  |  | 						range = (float)(end_sel - start_sel) + 2.0f; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						for (bezt = &nu->bezt[start_sel], a = start_sel; a <= end_sel; a++, bezt++) { | 
					
						
							|  |  |  | 							fac = (float)(1 + a - start_sel) / range; | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 							BEZT_VALUE(bezt) = start_rad * (1.0f - fac) + end_rad * fac; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | #undef BEZT_VALUE
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (nu->bp) { | 
					
						
							| 
									
										
										
										
											2015-08-02 13:54:06 +10:00
										 |  |  | #define BP_VALUE(bp) (*((float *)((char *)(bp) + bp_offset)))
 | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			/* Same as above, keep these the same! */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			for (last_sel = 0; last_sel < nu->pntsu; last_sel++) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				/* loop over selection segments of a curve, smooth each */ | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				/* Start BezTriple code, this is duplicated below for points, make sure these functions stay in sync */ | 
					
						
							| 
									
										
										
										
											2011-01-12 03:41:12 +00:00
										 |  |  | 				start_sel = -1; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				for (bp = &nu->bp[last_sel], a = last_sel; a < nu->pntsu; a++, bp++) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					if (bp->f1 & SELECT) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						start_sel = a; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-09 00:41:09 +00:00
										 |  |  | 				/* in case there are no other selected verts */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				end_sel = start_sel; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				for (bp = &nu->bp[start_sel + 1], a = start_sel + 1; a < nu->pntsu; a++, bp++) { | 
					
						
							|  |  |  | 					if ((bp->f1 & SELECT) == 0) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					end_sel = a; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				if (start_sel == -1) { | 
					
						
							|  |  |  | 					last_sel = nu->pntsu; /* next... */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					last_sel = end_sel; /* before we modify it */ | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					/* now blend between start and end sel */ | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 					start_rad = end_rad = FLT_MAX; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					if (start_sel == end_sel) { | 
					
						
							|  |  |  | 						/* simple, only 1 point selected */ | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 						if (start_sel > 0) start_rad = BP_VALUE(&nu->bp[start_sel - 1]); | 
					
						
							|  |  |  | 						if (end_sel != -1 && end_sel < nu->pntsu) end_rad = BP_VALUE(&nu->bp[start_sel + 1]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if      (start_rad != FLT_MAX && end_rad != FLT_MAX) BP_VALUE(&nu->bp[start_sel]) = (start_rad + end_rad) / 2; | 
					
						
							|  |  |  | 						else if (start_rad != FLT_MAX)                       BP_VALUE(&nu->bp[start_sel]) = start_rad; | 
					
						
							|  |  |  | 						else if (end_rad   != FLT_MAX)                       BP_VALUE(&nu->bp[start_sel]) = end_rad; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						/* if endpoints selected, then use them */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						if (start_sel == 0) { | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 							start_rad = BP_VALUE(&nu->bp[start_sel]); | 
					
						
							| 
									
										
										
										
											2012-03-18 07:38:51 +00:00
										 |  |  | 							start_sel++; /* we don't want to edit the selected endpoint */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						else { | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 							start_rad = BP_VALUE(&nu->bp[start_sel - 1]); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						if (end_sel == nu->pntsu - 1) { | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 							end_rad = BP_VALUE(&nu->bp[end_sel]); | 
					
						
							| 
									
										
										
										
											2012-03-18 07:38:51 +00:00
										 |  |  | 							end_sel--; /* we don't want to edit the selected endpoint */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						else { | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 							end_rad = BP_VALUE(&nu->bp[end_sel + 1]); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						/* Now Blend between the points */ | 
					
						
							|  |  |  | 						range = (float)(end_sel - start_sel) + 2.0f; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						for (bp = &nu->bp[start_sel], a = start_sel; a <= end_sel; a++, bp++) { | 
					
						
							|  |  |  | 							fac = (float)(1 + a - start_sel) / range; | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 							BP_VALUE(bp) = start_rad * (1.0f - fac) + end_rad * fac; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | #undef BP_VALUE
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int curve_smooth_weight_exec(bContext *C, wmOperator *UNUSED(op)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	curve_smooth_value(editnurb, offsetof(BezTriple, weight), offsetof(BPoint, weight)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							|  |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CURVE_OT_smooth_weight(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							|  |  |  | 	ot->name = "Smooth Curve Weight"; | 
					
						
							|  |  |  | 	ot->description = "Interpolate weight of selected points"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_smooth_weight"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* api clastbacks */ | 
					
						
							|  |  |  | 	ot->exec = curve_smooth_weight_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							|  |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int curve_smooth_radius_exec(bContext *C, wmOperator *UNUSED(op)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	curve_smooth_value(editnurb, offsetof(BezTriple, radius), offsetof(BPoint, radius)); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | void CURVE_OT_smooth_radius(wmOperatorType *ot) | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Smooth Curve Radius"; | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 	ot->description = "Interpolate radii of selected points"; | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->idname = "CURVE_OT_smooth_radius"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api clastbacks */ | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | 	ot->exec = curve_smooth_radius_exec; | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-24 14:30:45 +00:00
										 |  |  | static int curve_smooth_tilt_exec(bContext *C, wmOperator *UNUSED(op)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	curve_smooth_value(editnurb, offsetof(BezTriple, alfa), offsetof(BPoint, alfa)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							|  |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CURVE_OT_smooth_tilt(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							|  |  |  | 	ot->name = "Smooth Curve Tilt"; | 
					
						
							|  |  |  | 	ot->description = "Interpolate tilt of selected points"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_smooth_tilt"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* api clastbacks */ | 
					
						
							|  |  |  | 	ot->exec = curve_smooth_tilt_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							|  |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | /********************** hide operator *********************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int hide_exec(bContext *C, wmOperator *op) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	Curve *cu = obedit->data; | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							|  |  |  | 	BezTriple *bezt; | 
					
						
							| 
									
										
										
										
											2014-02-03 18:55:59 +11:00
										 |  |  | 	int a, sel; | 
					
						
							|  |  |  | 	const bool invert = RNA_boolean_get(op->ptr, "unselected"); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (nu->type == CU_BEZIER) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			bezt = nu->bezt; | 
					
						
							|  |  |  | 			a = nu->pntsu; | 
					
						
							|  |  |  | 			sel = 0; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				if (invert == 0 && BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt)) { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 					select_beztriple(bezt, DESELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bezt->hide = 1; | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				else if (invert && !BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt)) { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 					select_beztriple(bezt, DESELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bezt->hide = 1; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (bezt->hide) sel++; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				bezt++; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			if (sel == nu->pntsu) nu->hide = 1; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			bp = nu->bp; | 
					
						
							|  |  |  | 			a = nu->pntsu * nu->pntsv; | 
					
						
							|  |  |  | 			sel = 0; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				if (invert == 0 && (bp->f1 & SELECT)) { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 					select_bpoint(bp, DESELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bp->hide = 1; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				else if (invert && (bp->f1 & SELECT) == 0) { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 					select_bpoint(bp, DESELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bp->hide = 1; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (bp->hide) sel++; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				bp++; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			if (sel == nu->pntsu * nu->pntsv) nu->hide = 1; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 	BKE_curve_nurb_vert_active_validate(obedit->data); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CURVE_OT_hide(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Hide Selected"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_hide"; | 
					
						
							| 
									
										
										
										
											2012-05-04 15:00:36 +00:00
										 |  |  | 	ot->description = "Hide (un)selected control points"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = hide_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* props */ | 
					
						
							| 
									
										
										
										
											2011-09-19 12:26:20 +00:00
										 |  |  | 	RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected"); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | /********************** reveal operator *********************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-15 01:36:14 +00:00
										 |  |  | static int reveal_exec(bContext *C, wmOperator *UNUSED(op)) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							|  |  |  | 	BezTriple *bezt; | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							|  |  |  | 		nu->hide = 0; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (nu->type == CU_BEZIER) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			bezt = nu->bezt; | 
					
						
							|  |  |  | 			a = nu->pntsu; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							|  |  |  | 				if (bezt->hide) { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 					select_beztriple(bezt, SELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bezt->hide = 0; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				bezt++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			bp = nu->bp; | 
					
						
							|  |  |  | 			a = nu->pntsu * nu->pntsv; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							|  |  |  | 				if (bp->hide) { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 					select_bpoint(bp, SELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bp->hide = 0; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				bp++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | void CURVE_OT_reveal(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Reveal Hidden"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_reveal"; | 
					
						
							| 
									
										
										
										
											2012-05-04 15:00:36 +00:00
										 |  |  | 	ot->description = "Show again hidden control points"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = reveal_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | /********************** subdivide operator *********************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | /** Divide the line segments associated with the currently selected
 | 
					
						
							|  |  |  |  * curve nodes (Bezier or NURB). If there are no valid segment | 
					
						
							|  |  |  |  * selections within the current selection, nothing happens. | 
					
						
							| 
									
										
										
										
											2011-11-05 01:48:10 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | static void subdividenurb(Object *obedit, int number_cuts) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Curve *cu = obedit->data; | 
					
						
							|  |  |  | 	EditNurb *editnurb = cu->editnurb; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu; | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 	BezTriple *bezt, *beztnew, *beztn; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	BPoint *bp, *prevbp, *bpnew, *bpn; | 
					
						
							|  |  |  | 	float vec[15]; | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 	int a, b, sel, amount, *usel, *vsel, i; | 
					
						
							|  |  |  | 	float factor; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-07 02:48:14 +00:00
										 |  |  | 	// printf("*** subdivideNurb: entering subdivide\n");
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->nurbs.first; nu; nu = nu->next) { | 
					
						
							|  |  |  | 		amount = 0; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (nu->type == CU_BEZIER) { | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 			BezTriple *nextbezt; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			/*
 | 
					
						
							|  |  |  | 			 * Insert a point into a 2D Bezier curve. | 
					
						
							|  |  |  | 			 * Endpoints are preserved. Otherwise, all selected and inserted points are | 
					
						
							|  |  |  | 			 * newly created. Old points are discarded. | 
					
						
							|  |  |  | 			 */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			/* count */ | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 			a = nu->pntsu; | 
					
						
							|  |  |  | 			bezt = nu->bezt; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							| 
									
										
										
										
											2013-07-24 13:56:36 +00:00
										 |  |  | 				nextbezt = BKE_nurb_bezt_get_next(nu, bezt); | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 				if (nextbezt == NULL) { | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt) && BEZT_ISSEL_ANY_HIDDENHANDLES(cu, nextbezt)) { | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 					amount += number_cuts; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				bezt++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (amount) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				/* insert */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				beztnew = (BezTriple *)MEM_mallocN((amount + nu->pntsu) * sizeof(BezTriple), "subdivNurb"); | 
					
						
							|  |  |  | 				beztn = beztnew; | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 				a = nu->pntsu; | 
					
						
							|  |  |  | 				bezt = nu->bezt; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				while (a--) { | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 					memcpy(beztn, bezt, sizeof(BezTriple)); | 
					
						
							|  |  |  | 					keyIndex_updateBezt(editnurb, bezt, beztn, 1); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					beztn++; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-24 13:56:36 +00:00
										 |  |  | 					nextbezt = BKE_nurb_bezt_get_next(nu, bezt); | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 					if (nextbezt == NULL) { | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 					if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt) && BEZT_ISSEL_ANY_HIDDENHANDLES(cu, nextbezt)) { | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 						float prevvec[3][3]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 						memcpy(prevvec, bezt->vec, sizeof(float) * 9); | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 						for (i = 0; i < number_cuts; i++) { | 
					
						
							|  |  |  | 							factor = 1.0f / (number_cuts + 1 - i); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 							memcpy(beztn, nextbezt, sizeof(BezTriple)); | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 							/* midpoint subdividing */ | 
					
						
							| 
									
										
										
										
											2010-03-24 17:52:51 +00:00
										 |  |  | 							interp_v3_v3v3(vec, prevvec[1], prevvec[2], factor); | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 							interp_v3_v3v3(vec + 3, prevvec[2], nextbezt->vec[0], factor); | 
					
						
							|  |  |  | 							interp_v3_v3v3(vec + 6, nextbezt->vec[0], nextbezt->vec[1], factor); | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							interp_v3_v3v3(vec + 9, vec, vec + 3, factor); | 
					
						
							|  |  |  | 							interp_v3_v3v3(vec + 12, vec + 3, vec + 6, factor); | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 							/* change handle of prev beztn */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							copy_v3_v3((beztn - 1)->vec[2], vec); | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 							/* new point */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							copy_v3_v3(beztn->vec[0], vec + 9); | 
					
						
							|  |  |  | 							interp_v3_v3v3(beztn->vec[1], vec + 9, vec + 12, factor); | 
					
						
							|  |  |  | 							copy_v3_v3(beztn->vec[2], vec + 12); | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 							/* handle of next bezt */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							if (a == 0 && i == number_cuts - 1 && (nu->flagu & CU_NURB_CYCLIC)) { copy_v3_v3(beztnew->vec[0], vec + 6); } | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 							else                                                                { copy_v3_v3(nextbezt->vec[0], vec + 6); } | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 							beztn->radius = (bezt->radius + nextbezt->radius) / 2; | 
					
						
							|  |  |  | 							beztn->weight = (bezt->weight + nextbezt->weight) / 2; | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-24 19:14:10 +00:00
										 |  |  | 							memcpy(prevvec, beztn->vec, sizeof(float) * 9); | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 							beztn++; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					bezt++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				MEM_freeN(nu->bezt); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				nu->bezt = beztnew; | 
					
						
							|  |  |  | 				nu->pntsu += amount; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 				BKE_nurb_handles_calc(nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-04-21 12:51:47 +00:00
										 |  |  | 		} /* End of 'if (nu->type == CU_BEZIER)' */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		else if (nu->pntsv == 1) { | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 			BPoint *nextbp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			/*
 | 
					
						
							|  |  |  | 			 * All flat lines (ie. co-planar), except flat Nurbs. Flat NURB curves | 
					
						
							|  |  |  | 			 * are handled together with the regular NURB plane division, as it | 
					
						
							|  |  |  | 			 * should be. I split it off just now, let's see if it is | 
					
						
							|  |  |  | 			 * stable... nzc 30-5-'00 | 
					
						
							|  |  |  | 			 */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			/* count */ | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 			a = nu->pntsu; | 
					
						
							|  |  |  | 			bp = nu->bp; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							| 
									
										
										
										
											2013-07-24 13:56:36 +00:00
										 |  |  | 				nextbp = BKE_nurb_bpoint_get_next(nu, bp); | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 				if (nextbp == NULL) { | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if ((bp->f1 & SELECT) && (nextbp->f1 & SELECT)) { | 
					
						
							|  |  |  | 					amount += number_cuts; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				bp++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (amount) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				/* insert */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				bpnew = (BPoint *)MEM_mallocN((amount + nu->pntsu) * sizeof(BPoint), "subdivNurb2"); | 
					
						
							|  |  |  | 				bpn = bpnew; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 				a = nu->pntsu; | 
					
						
							|  |  |  | 				bp = nu->bp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				while (a--) { | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 					/* Copy "old" point. */ | 
					
						
							|  |  |  | 					memcpy(bpn, bp, sizeof(BPoint)); | 
					
						
							|  |  |  | 					keyIndex_updateBP(editnurb, bp, bpn, 1); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					bpn++; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-24 13:56:36 +00:00
										 |  |  | 					nextbp = BKE_nurb_bpoint_get_next(nu, bp); | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 					if (nextbp == NULL) { | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if ((bp->f1 & SELECT) && (nextbp->f1 & SELECT)) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						// printf("*** subdivideNurb: insert 'linear' point\n");
 | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 						for (i = 0; i < number_cuts; i++) { | 
					
						
							|  |  |  | 							factor = (float)(i + 1) / (number_cuts + 1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 08:02:37 +00:00
										 |  |  | 							memcpy(bpn, nextbp, sizeof(BPoint)); | 
					
						
							|  |  |  | 							interp_v4_v4v4(bpn->vec, bp->vec, nextbp->vec, factor); | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 							bpn++; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					bp++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				MEM_freeN(nu->bp); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				nu->bp = bpnew; | 
					
						
							|  |  |  | 				nu->pntsu += amount; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (nu->type & CU_NURBS) { | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 					BKE_nurb_knot_calc_u(nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-27 19:40:36 +00:00
										 |  |  | 		} /* End of 'else if (nu->pntsv == 1)' */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		else if (nu->type == CU_NURBS) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			/* This is a very strange test ... */ | 
					
						
							|  |  |  | 			/**
 | 
					
						
							|  |  |  | 			 * Subdivide NURB surfaces - nzc 30-5-'00 - | 
					
						
							|  |  |  | 			 * | 
					
						
							|  |  |  | 			 * Subdivision of a NURB curve can be effected by adding a | 
					
						
							|  |  |  | 			 * control point (insertion of a knot), or by raising the | 
					
						
							|  |  |  | 			 * degree of the functions used to build the NURB. The | 
					
						
							|  |  |  | 			 * expression | 
					
						
							|  |  |  | 			 * | 
					
						
							|  |  |  | 			 *     degree = #knots - #controlpoints + 1 (J Walter piece) | 
					
						
							|  |  |  | 			 *     degree = #knots - #controlpoints     (Blender | 
					
						
							|  |  |  | 			 *                                           implementation) | 
					
						
							|  |  |  | 			 *       ( this is confusing.... what is true? Another concern | 
					
						
							|  |  |  | 			 *       is that the JW piece allows the curve to become | 
					
						
							|  |  |  | 			 *       explicitly 1st order derivative discontinuous, while | 
					
						
							|  |  |  | 			 *       this is not what we want here... ) | 
					
						
							|  |  |  | 			 * | 
					
						
							|  |  |  | 			 * is an invariant for a single NURB curve. Raising the degree | 
					
						
							|  |  |  | 			 * of the NURB is done elsewhere; the degree is assumed | 
					
						
							|  |  |  | 			 * constant during this operation. Degree is a property shared | 
					
						
							|  |  |  | 			 * by all controlpoints in a curve (even though it is stored | 
					
						
							|  |  |  | 			 * per control point - this can be misleading). | 
					
						
							|  |  |  | 			 * Adding a knot is done by searching for the place in the | 
					
						
							|  |  |  | 			 * knot vector where a certain knot value must be inserted, or | 
					
						
							|  |  |  | 			 * by picking an appropriate knot value between two existing | 
					
						
							|  |  |  | 			 * ones. The number of controlpoints that is influenced by the | 
					
						
							|  |  |  | 			 * insertion depends on the order of the curve. A certain | 
					
						
							|  |  |  | 			 * minimum number of knots is needed to form high-order | 
					
						
							|  |  |  | 			 * curves, as can be seen from the equation above. In Blender, | 
					
						
							|  |  |  | 			 * currently NURBs may be up to 6th order, so we modify at | 
					
						
							|  |  |  | 			 * most 6 points. One point is added. For an n-degree curve, | 
					
						
							|  |  |  | 			 * n points are discarded, and n+1 points inserted | 
					
						
							|  |  |  | 			 * (so effectively, n points are modified).  (that holds for | 
					
						
							|  |  |  | 			 * the JW piece, but it seems not for our NURBs) | 
					
						
							|  |  |  | 			 * In practice, the knot spacing is copied, but the tail | 
					
						
							|  |  |  | 			 * (the points following the insertion point) need to be | 
					
						
							|  |  |  | 			 * offset to keep the knot series ascending. The knot series | 
					
						
							|  |  |  | 			 * is always a series of monotonically ascending integers in | 
					
						
							|  |  |  | 			 * Blender. When not enough control points are available to | 
					
						
							|  |  |  | 			 * fit the order, duplicates of the endpoints are added as | 
					
						
							|  |  |  | 			 * needed. | 
					
						
							|  |  |  | 			 */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			/* selection-arrays */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			usel = MEM_callocN(sizeof(int) * nu->pntsu, "subivideNurb3"); | 
					
						
							|  |  |  | 			vsel = MEM_callocN(sizeof(int) * nu->pntsv, "subivideNurb3"); | 
					
						
							|  |  |  | 			sel = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* Count the number of selected points. */ | 
					
						
							|  |  |  | 			bp = nu->bp; | 
					
						
							|  |  |  | 			for (a = 0; a < nu->pntsv; a++) { | 
					
						
							|  |  |  | 				for (b = 0; b < nu->pntsu; b++) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					if (bp->f1 & SELECT) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						usel[b]++; | 
					
						
							|  |  |  | 						vsel[a]++; | 
					
						
							|  |  |  | 						sel++; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					bp++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 			if (sel == (nu->pntsu * nu->pntsv)) {  /* subdivide entire nurb */ | 
					
						
							| 
									
										
										
										
											2012-03-03 16:31:46 +00:00
										 |  |  | 				/* Global subdivision is a special case of partial
 | 
					
						
							|  |  |  | 				 * subdivision. Strange it is considered separately... */ | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* count of nodes (after subdivision) along U axis */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				int countu = nu->pntsu + (nu->pntsu - 1) * number_cuts; | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* total count of nodes after subdivision */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				int tot = ((number_cuts + 1) * nu->pntsu - number_cuts) * ((number_cuts + 1) * nu->pntsv - number_cuts); | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				bpn = bpnew = MEM_mallocN(tot * sizeof(BPoint), "subdivideNurb4"); | 
					
						
							|  |  |  | 				bp = nu->bp; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				/* first subdivide rows */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				for (a = 0; a < nu->pntsv; a++) { | 
					
						
							|  |  |  | 					for (b = 0; b < nu->pntsu; b++) { | 
					
						
							|  |  |  | 						*bpn = *bp; | 
					
						
							| 
									
										
										
										
											2010-12-06 21:18:08 +00:00
										 |  |  | 						keyIndex_updateBP(editnurb, bp, bpn, 1); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						bpn++;  | 
					
						
							|  |  |  | 						bp++; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						if (b < nu->pntsu - 1) { | 
					
						
							|  |  |  | 							prevbp = bp - 1; | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 							for (i = 0; i < number_cuts; i++) { | 
					
						
							|  |  |  | 								factor = (float)(i + 1) / (number_cuts + 1); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 								*bpn = *bp; | 
					
						
							| 
									
										
										
										
											2010-03-24 17:52:51 +00:00
										 |  |  | 								interp_v4_v4v4(bpn->vec, prevbp->vec, bp->vec, factor); | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 								bpn++; | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bpn += number_cuts * countu; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				/* now insert new */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				bpn = bpnew + ((number_cuts + 1) * nu->pntsu - number_cuts); | 
					
						
							|  |  |  | 				bp = bpnew + (number_cuts + 1) * ((number_cuts + 1) * nu->pntsu - number_cuts); | 
					
						
							|  |  |  | 				prevbp = bpnew; | 
					
						
							|  |  |  | 				for (a = 1; a < nu->pntsv; a++) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					for (b = 0; b < (number_cuts + 1) * nu->pntsu - number_cuts; b++) { | 
					
						
							|  |  |  | 						BPoint *tmp = bpn; | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 						for (i = 0; i < number_cuts; i++) { | 
					
						
							|  |  |  | 							factor = (float)(i + 1) / (number_cuts + 1); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							*tmp = *bp; | 
					
						
							| 
									
										
										
										
											2010-03-24 17:52:51 +00:00
										 |  |  | 							interp_v4_v4v4(tmp->vec, prevbp->vec, bp->vec, factor); | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 							tmp += countu; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						bp++;  | 
					
						
							|  |  |  | 						prevbp++; | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 						bpn++; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bp += number_cuts * countu; | 
					
						
							|  |  |  | 					bpn += number_cuts * countu; | 
					
						
							|  |  |  | 					prevbp += number_cuts * countu; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				MEM_freeN(nu->bp); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				nu->bp = bpnew; | 
					
						
							|  |  |  | 				nu->pntsu = (number_cuts + 1) * nu->pntsu - number_cuts; | 
					
						
							|  |  |  | 				nu->pntsv = (number_cuts + 1) * nu->pntsv - number_cuts; | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 				BKE_nurb_knot_calc_u(nu); | 
					
						
							|  |  |  | 				BKE_nurb_knot_calc_v(nu); | 
					
						
							| 
									
										
										
										
											2012-10-27 10:42:28 +00:00
										 |  |  | 			} /* End of 'if (sel == nu->pntsu * nu->pntsv)' (subdivide entire NURB) */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			else { | 
					
						
							|  |  |  | 				/* subdivide in v direction? */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				sel = 0; | 
					
						
							|  |  |  | 				for (a = 0; a < nu->pntsv - 1; a++) { | 
					
						
							|  |  |  | 					if (vsel[a] == nu->pntsu && vsel[a + 1] == nu->pntsu) sel += number_cuts; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (sel) {   /* V ! */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					bpn = bpnew = MEM_mallocN((sel + nu->pntsv) * nu->pntsu * sizeof(BPoint), "subdivideNurb4"); | 
					
						
							|  |  |  | 					bp = nu->bp; | 
					
						
							|  |  |  | 					for (a = 0; a < nu->pntsv; a++) { | 
					
						
							|  |  |  | 						for (b = 0; b < nu->pntsu; b++) { | 
					
						
							|  |  |  | 							*bpn = *bp; | 
					
						
							| 
									
										
										
										
											2010-12-06 21:18:08 +00:00
										 |  |  | 							keyIndex_updateBP(editnurb, bp, bpn, 1); | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 							bpn++; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 							bp++; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						if ( (a < nu->pntsv - 1) && vsel[a] == nu->pntsu && vsel[a + 1] == nu->pntsu) { | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 							for (i = 0; i < number_cuts; i++) { | 
					
						
							|  |  |  | 								factor = (float)(i + 1) / (number_cuts + 1); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 								prevbp = bp - nu->pntsu; | 
					
						
							|  |  |  | 								for (b = 0; b < nu->pntsu; b++) { | 
					
						
							|  |  |  | 									/*
 | 
					
						
							|  |  |  | 									 * This simple bisection must be replaces by a | 
					
						
							|  |  |  | 									 * subtle resampling of a number of points. Our | 
					
						
							|  |  |  | 									 * task is made slightly easier because each | 
					
						
							|  |  |  | 									 * point in our curve is a separate data | 
					
						
							|  |  |  | 									 * node. (is it?) | 
					
						
							|  |  |  | 									 */ | 
					
						
							|  |  |  | 									*bpn = *prevbp; | 
					
						
							|  |  |  | 									interp_v4_v4v4(bpn->vec, prevbp->vec, bp->vec, factor); | 
					
						
							|  |  |  | 									bpn++; | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 									prevbp++; | 
					
						
							|  |  |  | 									bp++; | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 								bp -= nu->pntsu; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					MEM_freeN(nu->bp); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					nu->bp = bpnew; | 
					
						
							|  |  |  | 					nu->pntsv += sel; | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 					BKE_nurb_knot_calc_v(nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					/* or in u direction? */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					sel = 0; | 
					
						
							|  |  |  | 					for (a = 0; a < nu->pntsu - 1; a++) { | 
					
						
							|  |  |  | 						if (usel[a] == nu->pntsv && usel[a + 1] == nu->pntsv) sel += number_cuts; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					if (sel) {  /* U ! */ | 
					
						
							|  |  |  | 						/* Inserting U points is sort of 'default' Flat curves only get */ | 
					
						
							|  |  |  | 						/* U points inserted in them.                                   */ | 
					
						
							|  |  |  | 						bpn = bpnew = MEM_mallocN((sel + nu->pntsu) * nu->pntsv * sizeof(BPoint), "subdivideNurb4"); | 
					
						
							|  |  |  | 						bp = nu->bp; | 
					
						
							|  |  |  | 						for (a = 0; a < nu->pntsv; a++) { | 
					
						
							|  |  |  | 							for (b = 0; b < nu->pntsu; b++) { | 
					
						
							|  |  |  | 								*bpn = *bp; | 
					
						
							| 
									
										
										
										
											2010-12-06 21:18:08 +00:00
										 |  |  | 								keyIndex_updateBP(editnurb, bp, bpn, 1); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 								bpn++;  | 
					
						
							|  |  |  | 								bp++; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 								if ( (b < nu->pntsu - 1) && usel[b] == nu->pntsv && usel[b + 1] == nu->pntsv) { | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 									/*
 | 
					
						
							| 
									
										
										
										
											2012-03-03 16:31:46 +00:00
										 |  |  | 									 * One thing that bugs me here is that the | 
					
						
							|  |  |  | 									 * orders of things are not the same as in | 
					
						
							|  |  |  | 									 * the JW piece. Also, this implies that we | 
					
						
							|  |  |  | 									 * handle at most 3rd order curves? I miss | 
					
						
							|  |  |  | 									 * some symmetry here... | 
					
						
							|  |  |  | 									 */ | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 									for (i = 0; i < number_cuts; i++) { | 
					
						
							|  |  |  | 										factor = (float)(i + 1) / (number_cuts + 1); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 										prevbp = bp - 1; | 
					
						
							|  |  |  | 										*bpn = *prevbp; | 
					
						
							|  |  |  | 										interp_v4_v4v4(bpn->vec, prevbp->vec, bp->vec, factor); | 
					
						
							|  |  |  | 										bpn++; | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 									} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						MEM_freeN(nu->bp); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						nu->bp = bpnew; | 
					
						
							|  |  |  | 						nu->pntsu += sel; | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 						BKE_nurb_knot_calc_u(nu); /* shift knots forward */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			MEM_freeN(usel);  | 
					
						
							|  |  |  | 			MEM_freeN(vsel); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-21 12:51:47 +00:00
										 |  |  | 		} /* End of 'if (nu->type == CU_NURBS)'  */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int subdivide_exec(bContext *C, wmOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	int number_cuts = RNA_int_get(op->ptr, "number_cuts"); | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	subdividenurb(obedit, number_cuts); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-16 08:04:12 +00:00
										 |  |  | 	if (ED_curve_updateAnimPaths(obedit->data)) | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | void CURVE_OT_subdivide(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-20 22:27:08 +00:00
										 |  |  | 	PropertyRNA *prop; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Subdivide"; | 
					
						
							|  |  |  | 	ot->description = "Subdivide selected segments"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_subdivide"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = subdivide_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-21 16:06:44 +02:00
										 |  |  | 	prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, 1000, "Number of cuts", "", 1, 10); | 
					
						
							| 
									
										
										
										
											2012-03-20 22:27:08 +00:00
										 |  |  | 	/* avoid re-using last var because it can cause _very_ high poly meshes and annoy users (or worse crash) */ | 
					
						
							|  |  |  | 	RNA_def_property_flag(prop, PROP_SKIP_SAVE); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | /******************** find nearest ************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-08 23:24:16 +10:00
										 |  |  | static void ED_curve_pick_vert__doClosest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-10-10 01:22:19 +00:00
										 |  |  | 	struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; float dist; int hpoint, select; float mval_fl[2]; } *data = userData; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	short flag; | 
					
						
							| 
									
										
										
										
											2012-10-10 01:22:19 +00:00
										 |  |  | 	float dist_test; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (bp) { | 
					
						
							|  |  |  | 		flag = bp->f1; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		if (beztindex == 0) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			flag = bezt->f1; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		else if (beztindex == 1) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			flag = bezt->f2; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			flag = bezt->f3; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-10 01:22:19 +00:00
										 |  |  | 	dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); | 
					
						
							|  |  |  | 	if ((flag & SELECT) == data->select) dist_test += 5.0f; | 
					
						
							|  |  |  | 	if (bezt && beztindex == 1) dist_test += 3.0f;  /* middle points get a small disadvantage */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-10 01:22:19 +00:00
										 |  |  | 	if (dist_test < data->dist) { | 
					
						
							|  |  |  | 		data->dist = dist_test; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		data->bp = bp; | 
					
						
							|  |  |  | 		data->bezt = bezt; | 
					
						
							|  |  |  | 		data->nurb = nu; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		data->hpoint = bezt ? beztindex : 0; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-08 23:24:16 +10:00
										 |  |  | bool ED_curve_pick_vert( | 
					
						
							|  |  |  |         ViewContext *vc, short sel, const int mval[2], | 
					
						
							|  |  |  |         Nurb **r_nurb, BezTriple **r_bezt, BPoint **r_bp, short *r_handle) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-27 19:40:36 +00:00
										 |  |  | 	/* (sel == 1): selected gets a disadvantage */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	/* in nurb and bezt or bp the nearest is written */ | 
					
						
							|  |  |  | 	/* return 0 1 2: handlepunt */ | 
					
						
							| 
									
										
										
										
											2012-10-10 01:22:19 +00:00
										 |  |  | 	struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; float dist; int hpoint, select; float mval_fl[2]; } data = {NULL}; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-11 15:34:19 +11:00
										 |  |  | 	data.dist = ED_view3d_select_dist_px(); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	data.hpoint = 0; | 
					
						
							|  |  |  | 	data.select = sel; | 
					
						
							| 
									
										
										
										
											2012-10-10 01:22:19 +00:00
										 |  |  | 	data.mval_fl[0] = mval[0]; | 
					
						
							|  |  |  | 	data.mval_fl[1] = mval[1]; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 	ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); | 
					
						
							| 
									
										
										
										
											2015-07-08 23:24:16 +10:00
										 |  |  | 	nurbs_foreachScreenVert(vc, ED_curve_pick_vert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-08 23:24:16 +10:00
										 |  |  | 	*r_nurb = data.nurb; | 
					
						
							|  |  |  | 	*r_bezt = data.bezt; | 
					
						
							|  |  |  | 	*r_bp = data.bp; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-08 23:24:16 +10:00
										 |  |  | 	if (r_handle) { | 
					
						
							|  |  |  | 		*r_handle = data.hpoint; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (data.bezt || data.bp); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | static void findselectedNurbvert( | 
					
						
							|  |  |  |         Curve *cu, | 
					
						
							|  |  |  |         Nurb **r_nu, BezTriple **r_bezt, BPoint **r_bp) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* in nu and (bezt or bp) selected are written if there's 1 sel.  */ | 
					
						
							|  |  |  | 	/* if more points selected in 1 spline: return only nu, bezt and bp are 0 */ | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 	ListBase *editnurb = &cu->editnurb->nurbs; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu1; | 
					
						
							|  |  |  | 	BezTriple *bezt1; | 
					
						
							|  |  |  | 	BPoint *bp1; | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 	*r_nu = NULL; | 
					
						
							|  |  |  | 	*r_bezt = NULL; | 
					
						
							|  |  |  | 	*r_bp = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu1 = editnurb->first; nu1; nu1 = nu1->next) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (nu1->type == CU_BEZIER) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			bezt1 = nu1->bezt; | 
					
						
							|  |  |  | 			a = nu1->pntsu; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt1)) { | 
					
						
							|  |  |  | 					if (*r_nu != NULL && *r_nu != nu1) { | 
					
						
							|  |  |  | 						*r_nu = NULL; | 
					
						
							|  |  |  | 						*r_bp = NULL; | 
					
						
							|  |  |  | 						*r_bezt = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						return; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 					else if (*r_bezt || *r_bp) { | 
					
						
							|  |  |  | 						*r_bp = NULL; | 
					
						
							|  |  |  | 						*r_bezt = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 						*r_bezt = bezt1; | 
					
						
							|  |  |  | 						*r_nu = nu1; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				bezt1++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			bp1 = nu1->bp; | 
					
						
							|  |  |  | 			a = nu1->pntsu * nu1->pntsv; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				if (bp1->f1 & SELECT) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 					if (*r_nu != NULL && *r_nu != nu1) { | 
					
						
							|  |  |  | 						*r_bp = NULL; | 
					
						
							|  |  |  | 						*r_bezt = NULL; | 
					
						
							|  |  |  | 						*r_nu = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						return; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 					else if (*r_bezt || *r_bp) { | 
					
						
							|  |  |  | 						*r_bp = NULL; | 
					
						
							|  |  |  | 						*r_bezt = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 						*r_bp = bp1; | 
					
						
							|  |  |  | 						*r_nu = nu1; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				bp1++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | /***************** set spline type operator *******************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int set_spline_type_exec(bContext *C, wmOperator *op) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu; | 
					
						
							| 
									
										
										
										
											2013-11-26 06:39:14 +11:00
										 |  |  | 	bool changed = false; | 
					
						
							| 
									
										
										
										
											2014-05-26 09:11:42 +10:00
										 |  |  | 	bool changed_size = false; | 
					
						
							| 
									
										
										
										
											2013-03-20 15:01:15 +00:00
										 |  |  | 	const bool use_handles = RNA_boolean_get(op->ptr, "use_handles"); | 
					
						
							|  |  |  | 	const int type = RNA_enum_get(op->ptr, "type"); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	if (type == CU_CARDINAL || type == CU_BSPLINE) { | 
					
						
							| 
									
										
										
										
											2012-10-26 17:32:50 +00:00
										 |  |  | 		BKE_report(op->reports, RPT_ERROR, "Not yet implemented"); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 		if (ED_curve_nurb_select_check(obedit->data, nu)) { | 
					
						
							| 
									
										
										
										
											2014-05-26 09:11:42 +10:00
										 |  |  | 			const int pntsu_prev = nu->pntsu; | 
					
						
							|  |  |  | 			if (BKE_nurb_type_convert(nu, type, use_handles)) { | 
					
						
							| 
									
										
										
										
											2013-11-26 06:39:14 +11:00
										 |  |  | 				changed = true; | 
					
						
							| 
									
										
										
										
											2014-05-26 09:11:42 +10:00
										 |  |  | 				if (pntsu_prev != nu->pntsu) { | 
					
						
							|  |  |  | 					changed_size = true; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				BKE_report(op->reports, RPT_ERROR, "No conversion possible"); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-26 06:39:14 +11:00
										 |  |  | 	if (changed) { | 
					
						
							| 
									
										
										
										
											2012-04-16 08:04:12 +00:00
										 |  |  | 		if (ED_curve_updateAnimPaths(obedit->data)) | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 		DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							| 
									
										
										
										
											2009-09-16 17:43:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-26 09:11:42 +10:00
										 |  |  | 		if (changed_size) { | 
					
						
							|  |  |  | 			Curve *cu = obedit->data; | 
					
						
							|  |  |  | 			cu->actvert = CU_ACT_NONE; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 17:43:09 +00:00
										 |  |  | 		return OPERATOR_FINISHED; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-29 02:15:13 +00:00
										 |  |  | void CURVE_OT_spline_type_set(wmOperatorType *ot) | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	static EnumPropertyItem type_items[] = { | 
					
						
							| 
									
										
										
										
											2009-06-16 00:52:21 +00:00
										 |  |  | 		{CU_POLY, "POLY", 0, "Poly", ""}, | 
					
						
							|  |  |  | 		{CU_BEZIER, "BEZIER", 0, "Bezier", ""}, | 
					
						
							| 
									
										
										
										
											2009-09-16 17:43:09 +00:00
										 |  |  | //		{CU_CARDINAL, "CARDINAL", 0, "Cardinal", ""},
 | 
					
						
							|  |  |  | //		{CU_BSPLINE, "B_SPLINE", 0, "B-Spline", ""},
 | 
					
						
							| 
									
										
										
										
											2009-06-16 00:52:21 +00:00
										 |  |  | 		{CU_NURBS, "NURBS", 0, "NURBS", ""}, | 
					
						
							| 
									
										
										
										
											2012-06-05 21:54:21 +00:00
										 |  |  | 		{0, NULL, 0, NULL, NULL} | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Set Spline Type"; | 
					
						
							| 
									
										
										
										
											2011-05-07 02:48:14 +00:00
										 |  |  | 	ot->description = "Set type of active spline"; | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->idname = "CURVE_OT_spline_type_set"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = set_spline_type_exec; | 
					
						
							|  |  |  | 	ot->invoke = WM_menu_invoke; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* properties */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->prop = RNA_def_enum(ot->srna, "type", type_items, CU_POLY, "Type", "Spline type"); | 
					
						
							| 
									
										
										
										
											2013-03-20 15:01:15 +00:00
										 |  |  | 	RNA_def_boolean(ot->srna, "use_handles", 0, "Handles", "Use handles when converting bezier curves into polygons"); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | /***************** set handle type operator *******************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int set_handle_type_exec(bContext *C, wmOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 	BKE_nurbList_handles_set(editnurb, RNA_enum_get(op->ptr, "type")); | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-29 02:15:13 +00:00
										 |  |  | void CURVE_OT_handle_type_set(wmOperatorType *ot) | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-14 10:17:13 +00:00
										 |  |  | 	/* keep in sync with graphkeys_handle_type_items */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	static EnumPropertyItem editcurve_handle_type_items[] = { | 
					
						
							| 
									
										
										
										
											2010-12-09 19:06:45 +00:00
										 |  |  | 		{HD_AUTO, "AUTOMATIC", 0, "Automatic", ""}, | 
					
						
							|  |  |  | 		{HD_VECT, "VECTOR", 0, "Vector", ""}, | 
					
						
							| 
									
										
										
										
											2010-12-14 10:17:13 +00:00
										 |  |  | 		{5, "ALIGNED", 0, "Aligned", ""}, | 
					
						
							|  |  |  | 		{6, "FREE_ALIGN", 0, "Free", ""}, | 
					
						
							| 
									
										
										
										
											2009-06-16 00:52:21 +00:00
										 |  |  | 		{3, "TOGGLE_FREE_ALIGN", 0, "Toggle Free/Align", ""}, | 
					
						
							| 
									
										
										
										
											2012-06-05 21:54:21 +00:00
										 |  |  | 		{0, NULL, 0, NULL, NULL} | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Set Handle Type"; | 
					
						
							| 
									
										
										
										
											2011-04-04 20:31:01 +00:00
										 |  |  | 	ot->description = "Set type of handles for selected control points"; | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->idname = "CURVE_OT_handle_type_set"; | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->invoke = WM_menu_invoke; | 
					
						
							|  |  |  | 	ot->exec = set_handle_type_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editcurve; | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* properties */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->prop = RNA_def_enum(ot->srna, "type", editcurve_handle_type_items, 1, "Type", "Spline type"); | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-14 02:32:48 +11:00
										 |  |  | /***************** recalculate handles operator **********************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int curve_normals_make_consistent_exec(bContext *C, wmOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							|  |  |  | 	const bool calc_length = RNA_boolean_get(op->ptr, "calc_length"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BKE_nurbList_handles_recalculate(editnurb, calc_length, SELECT); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							|  |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CURVE_OT_normals_make_consistent(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							|  |  |  | 	ot->name = "Recalc Normals"; | 
					
						
							|  |  |  | 	ot->description = "Recalculate the direction of selected handles"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_normals_make_consistent"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							|  |  |  | 	ot->exec = curve_normals_make_consistent_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editcurve; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							|  |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* props */ | 
					
						
							|  |  |  | 	RNA_def_boolean(ot->srna, "calc_length", false, "Length", "Recalculate handle length"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | /***************** make segment operator **********************/ | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | /* ******************** SKINNING LOFTING!!! ******************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | static void switchdirection_knots(float *base, int tot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float *fp1, *fp2, *tempf; | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	if (base == NULL || tot == 0) return; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* reverse knots */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	a = tot; | 
					
						
							|  |  |  | 	fp1 = base; | 
					
						
							|  |  |  | 	fp2 = fp1 + (a - 1); | 
					
						
							|  |  |  | 	a /= 2; | 
					
						
							|  |  |  | 	while (fp1 != fp2 && a > 0) { | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 		SWAP(float, *fp1, *fp2); | 
					
						
							|  |  |  | 		a--; | 
					
						
							|  |  |  | 		fp1++;  | 
					
						
							|  |  |  | 		fp2--; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-03 23:18:09 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	/* and make in increasing order again */ | 
					
						
							| 
									
										
										
										
											2015-08-03 23:18:09 +10:00
										 |  |  | 	a = tot - 1; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	fp1 = base; | 
					
						
							| 
									
										
										
										
											2015-08-03 23:18:09 +10:00
										 |  |  | 	fp2 = tempf = MEM_mallocN(sizeof(float) * tot, "switchdirect"); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (a--) { | 
					
						
							| 
									
										
										
										
											2014-03-01 14:20:54 +11:00
										 |  |  | 		fp2[0] = fabsf(fp1[1] - fp1[0]); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 		fp1++; | 
					
						
							|  |  |  | 		fp2++; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-03 23:18:09 +10:00
										 |  |  | 	fp2[0] = 0.0f; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	a = tot - 1; | 
					
						
							|  |  |  | 	fp1 = base; | 
					
						
							|  |  |  | 	fp2 = tempf; | 
					
						
							|  |  |  | 	fp1[0] = 0.0; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	fp1++; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (a--) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		fp1[0] = fp1[-1] + fp2[0]; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 		fp1++; | 
					
						
							|  |  |  | 		fp2++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	MEM_freeN(tempf); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void rotate_direction_nurb(Nurb *nu) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	BPoint *bp1, *bp2, *temp; | 
					
						
							|  |  |  | 	int u, v; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2014-01-19 00:18:53 +06:00
										 |  |  | 	SWAP(int, nu->pntsu, nu->pntsv); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	SWAP(short, nu->orderu, nu->orderv); | 
					
						
							|  |  |  | 	SWAP(short, nu->resolu, nu->resolv); | 
					
						
							|  |  |  | 	SWAP(short, nu->flagu, nu->flagv); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	SWAP(float *, nu->knotsu, nu->knotsv); | 
					
						
							| 
									
										
										
										
											2012-04-29 17:55:54 +00:00
										 |  |  | 	switchdirection_knots(nu->knotsv, KNOTSV(nu)); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	temp = MEM_dupallocN(nu->bp); | 
					
						
							|  |  |  | 	bp1 = nu->bp; | 
					
						
							|  |  |  | 	for (v = 0; v < nu->pntsv; v++) { | 
					
						
							|  |  |  | 		for (u = 0; u < nu->pntsu; u++, bp1++) { | 
					
						
							|  |  |  | 			bp2 = temp + (nu->pntsu - u - 1) * (nu->pntsv) + v; | 
					
						
							|  |  |  | 			*bp1 = *bp2; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	MEM_freeN(temp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-28 03:52:21 +11:00
										 |  |  | static bool is_u_selected(Nurb *nu, int u) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							|  |  |  | 	int v; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* what about resolu == 2? */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	bp = &nu->bp[u]; | 
					
						
							|  |  |  | 	for (v = 0; v < nu->pntsv - 1; v++, bp += nu->pntsu) { | 
					
						
							| 
									
										
										
										
											2012-11-18 02:41:55 +00:00
										 |  |  | 		if ((v != 0) && (bp->f1 & SELECT)) { | 
					
						
							| 
									
										
										
										
											2014-04-01 11:34:00 +11:00
										 |  |  | 			return true; | 
					
						
							| 
									
										
										
										
											2012-11-18 02:41:55 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2014-04-01 11:34:00 +11:00
										 |  |  | 	return false; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct NurbSort { | 
					
						
							|  |  |  | 	struct NurbSort *next, *prev; | 
					
						
							|  |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	float vec[3]; | 
					
						
							|  |  |  | } NurbSort; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | static ListBase nsortbase = {NULL, NULL}; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | /*  static NurbSort *nusmain; */ /* this var seems to go unused... at least in this file */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | static void make_selection_list_nurb(Curve *cu, ListBase *editnurb) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ListBase nbase = {NULL, NULL}; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	NurbSort *nus, *nustest, *headdo, *taildo; | 
					
						
							|  |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							|  |  |  | 	float dist, headdist, taildist; | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 		if (ED_curve_nurb_select_check(cu, nu)) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			nus = (NurbSort *)MEM_callocN(sizeof(NurbSort), "sort"); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			BLI_addhead(&nbase, nus); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			nus->nu = nu; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			bp = nu->bp; | 
					
						
							|  |  |  | 			a = nu->pntsu; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							| 
									
										
										
										
											2010-04-21 12:27:48 +00:00
										 |  |  | 				add_v3_v3(nus->vec, bp->vec); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				bp++; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			mul_v3_fl(nus->vec, 1.0f / (float)nu->pntsu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* just add the first one */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	nus = nbase.first; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	BLI_remlink(&nbase, nus); | 
					
						
							| 
									
										
										
										
											2012-04-29 17:11:40 +00:00
										 |  |  | 	BLI_addtail(&nsortbase, nus); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* now add, either at head or tail, the closest one */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (nbase.first) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		headdist = taildist = 1.0e30; | 
					
						
							|  |  |  | 		headdo = taildo = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		nustest = nbase.first; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		while (nustest) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			dist = len_v3v3(nustest->vec, ((NurbSort *)nsortbase.first)->vec); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			if (dist < headdist) { | 
					
						
							|  |  |  | 				headdist = dist; | 
					
						
							|  |  |  | 				headdo = nustest; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			dist = len_v3v3(nustest->vec, ((NurbSort *)nsortbase.last)->vec); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			if (dist < taildist) { | 
					
						
							|  |  |  | 				taildist = dist; | 
					
						
							|  |  |  | 				taildo = nustest; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			nustest = nustest->next; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		if (headdist < taildist) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			BLI_remlink(&nbase, headdo); | 
					
						
							|  |  |  | 			BLI_addhead(&nsortbase, headdo); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			BLI_remlink(&nbase, taildo); | 
					
						
							|  |  |  | 			BLI_addtail(&nsortbase, taildo); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-29 19:04:31 +06:00
										 |  |  | static void merge_2_nurb(wmOperator *op, Curve *cu, ListBase *editnurb, Nurb *nu1, Nurb *nu2) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	BPoint *bp, *bp1, *bp2, *temp; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	float len1, len2; | 
					
						
							|  |  |  | 	int origu, u, v; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* first nurbs will be changed to make u = resolu-1 selected */ | 
					
						
							|  |  |  | 	/* 2nd nurbs will be changed to make u = 0 selected */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* first nurbs: u = resolu-1 selected */ | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 	if (is_u_selected(nu1, nu1->pntsu - 1)) { | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 		/* pass */ | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2012-05-27 19:40:36 +00:00
										 |  |  | 		/* For 2D curves blender uses (orderv = 0). It doesn't make any sense mathematically. */ | 
					
						
							|  |  |  | 		/* but after rotating (orderu = 0) will be confusing. */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		if (nu1->orderv == 0) nu1->orderv = 1; | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		rotate_direction_nurb(nu1); | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 		if (is_u_selected(nu1, nu1->pntsu - 1)) { | 
					
						
							|  |  |  | 			/* pass */ | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		else { | 
					
						
							|  |  |  | 			rotate_direction_nurb(nu1); | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 			if (is_u_selected(nu1, nu1->pntsu - 1)) { | 
					
						
							|  |  |  | 				/* pass */ | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			else { | 
					
						
							|  |  |  | 				rotate_direction_nurb(nu1); | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 				if (is_u_selected(nu1, nu1->pntsu - 1)) { | 
					
						
							|  |  |  | 					/* pass */ | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				else { | 
					
						
							|  |  |  | 					/* rotate again, now its OK! */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					if (nu1->pntsv != 1) rotate_direction_nurb(nu1); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					return; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* 2nd nurbs: u = 0 selected */ | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 	if (is_u_selected(nu2, 0)) { | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 		/* pass */ | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		if (nu2->orderv == 0) nu2->orderv = 1; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		rotate_direction_nurb(nu2); | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 		if (is_u_selected(nu2, 0)) { | 
					
						
							|  |  |  | 			/* pass */ | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		else { | 
					
						
							|  |  |  | 			rotate_direction_nurb(nu2); | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 			if (is_u_selected(nu2, 0)) { | 
					
						
							|  |  |  | 				/* pass */ | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			else { | 
					
						
							|  |  |  | 				rotate_direction_nurb(nu2); | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 				if (is_u_selected(nu2, 0)) { | 
					
						
							|  |  |  | 					/* pass */ | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				else { | 
					
						
							|  |  |  | 					/* rotate again, now its OK! */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					if (nu1->pntsu == 1) rotate_direction_nurb(nu1); | 
					
						
							|  |  |  | 					if (nu2->pntsv != 1) rotate_direction_nurb(nu2); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					return; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	if (nu1->pntsv != nu2->pntsv) { | 
					
						
							| 
									
										
										
										
											2012-10-26 17:32:50 +00:00
										 |  |  | 		BKE_report(op->reports, RPT_ERROR, "Resolution does not match"); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-04 04:35:12 +00:00
										 |  |  | 	/* ok, now nu1 has the rightmost column and nu2 the leftmost column selected */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	/* maybe we need a 'v' flip of nu2? */ | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	bp1 = &nu1->bp[nu1->pntsu - 1]; | 
					
						
							|  |  |  | 	bp2 = nu2->bp; | 
					
						
							|  |  |  | 	len1 = 0.0; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (v = 0; v < nu1->pntsv; v++, bp1 += nu1->pntsu, bp2 += nu2->pntsu) { | 
					
						
							|  |  |  | 		len1 += len_v3v3(bp1->vec, bp2->vec); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	bp1 = &nu1->bp[nu1->pntsu - 1]; | 
					
						
							|  |  |  | 	bp2 = &nu2->bp[nu2->pntsu * (nu2->pntsv - 1)]; | 
					
						
							|  |  |  | 	len2 = 0.0; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (v = 0; v < nu1->pntsv; v++, bp1 += nu1->pntsu, bp2 -= nu2->pntsu) { | 
					
						
							|  |  |  | 		len2 += len_v3v3(bp1->vec, bp2->vec); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* merge */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	origu = nu1->pntsu; | 
					
						
							|  |  |  | 	nu1->pntsu += nu2->pntsu; | 
					
						
							|  |  |  | 	if (nu1->orderu < 3 && nu1->orderu < nu1->pntsu) nu1->orderu++; | 
					
						
							|  |  |  | 	if (nu1->orderv < 3 && nu1->orderv < nu1->pntsv) nu1->orderv++; | 
					
						
							|  |  |  | 	temp = nu1->bp; | 
					
						
							|  |  |  | 	nu1->bp = MEM_mallocN(nu1->pntsu * nu1->pntsv * sizeof(BPoint), "mergeBP"); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	bp = nu1->bp; | 
					
						
							|  |  |  | 	bp1 = temp; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (v = 0; v < nu1->pntsv; v++) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		/* switch direction? */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		if (len1 < len2) bp2 = &nu2->bp[v * nu2->pntsu]; | 
					
						
							|  |  |  | 		else             bp2 = &nu2->bp[(nu1->pntsv - v - 1) * nu2->pntsu]; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		for (u = 0; u < nu1->pntsu; u++, bp++) { | 
					
						
							|  |  |  | 			if (u < origu) { | 
					
						
							| 
									
										
										
										
											2014-04-29 19:04:31 +06:00
										 |  |  | 				keyIndex_updateBP(cu->editnurb, bp1, bp, 1); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				*bp = *bp1; bp1++; | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 				select_bpoint(bp, SELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2014-04-29 19:04:31 +06:00
										 |  |  | 				keyIndex_updateBP(cu->editnurb, bp2, bp, 1); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				*bp = *bp2; bp2++; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (nu1->type == CU_NURBS) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		/* merge knots */ | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 		BKE_nurb_knot_calc_u(nu1); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 		/* make knots, for merged curved for example */ | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 		BKE_nurb_knot_calc_v(nu1); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	MEM_freeN(temp); | 
					
						
							|  |  |  | 	BLI_remlink(editnurb, nu2); | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 	BKE_nurb_free(nu2); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | static int merge_nurb(bContext *C, wmOperator *op) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							| 
									
										
										
										
											2014-04-29 19:04:31 +06:00
										 |  |  | 	Curve *cu = obedit->data; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	NurbSort *nus1, *nus2; | 
					
						
							| 
									
										
										
										
											2014-04-11 11:25:41 +10:00
										 |  |  | 	bool ok = true; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 	make_selection_list_nurb(cu, editnurb); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (nsortbase.first == nsortbase.last) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		BLI_freelistN(&nsortbase); | 
					
						
							| 
									
										
										
										
											2011-09-19 12:26:20 +00:00
										 |  |  | 		BKE_report(op->reports, RPT_ERROR, "Too few selections to merge"); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	nus1 = nsortbase.first; | 
					
						
							|  |  |  | 	nus2 = nus1->next; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* resolution match, to avoid uv rotations */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	if (nus1->nu->pntsv == 1) { | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 		if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsu == nus2->nu->pntsv) { | 
					
						
							|  |  |  | 			/* pass */ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			ok = 0; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	else if (nus2->nu->pntsv == 1) { | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 		if (nus2->nu->pntsu == nus1->nu->pntsu || nus2->nu->pntsu == nus1->nu->pntsv) { | 
					
						
							|  |  |  | 			/* pass */ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			ok = 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsv == nus2->nu->pntsv) { | 
					
						
							|  |  |  | 		/* pass */ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (nus1->nu->pntsu == nus2->nu->pntsv || nus1->nu->pntsv == nus2->nu->pntsu) { | 
					
						
							|  |  |  | 		/* pass */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		ok = 0; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	if (ok == 0) { | 
					
						
							| 
									
										
										
										
											2012-10-26 17:32:50 +00:00
										 |  |  | 		BKE_report(op->reports, RPT_ERROR, "Resolution does not match"); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		BLI_freelistN(&nsortbase); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-03-23 22:09:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (nus2) { | 
					
						
							| 
									
										
										
										
											2014-04-29 19:04:31 +06:00
										 |  |  | 		merge_2_nurb(op, cu, editnurb, nus1->nu, nus2->nu); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		nus2 = nus2->next; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	BLI_freelistN(&nsortbase); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 	BKE_curve_nurb_active_set(obedit->data, NULL); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | static int make_segment_exec(bContext *C, wmOperator *op) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* joins 2 curves */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	Curve *cu = obedit->data; | 
					
						
							|  |  |  | 	ListBase *nubase = object_editcurve_get(obedit); | 
					
						
							|  |  |  | 	Nurb *nu, *nu1 = NULL, *nu2 = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	BPoint *bp; | 
					
						
							| 
									
										
										
										
											2014-04-11 11:25:41 +10:00
										 |  |  | 	bool ok = false; | 
					
						
							| 
									
										
										
										
											2012-07-03 21:03:39 +00:00
										 |  |  | 	/* int a; */ /* UNUSED */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* first decide if this is a surface merge! */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	if (obedit->type == OB_SURF) nu = nubase->first; | 
					
						
							|  |  |  | 	else nu = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (nu) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 		const int nu_select_num = ED_curve_nurb_select_count(cu, nu); | 
					
						
							|  |  |  | 		if (nu_select_num) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (nu->pntsu > 1 && nu->pntsv > 1) { | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (nu_select_num > 1) { | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				/* only 1 selected, not first or last, a little complex, but intuitive */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				if (nu->pntsv == 1) { | 
					
						
							| 
									
										
										
										
											2014-03-17 21:48:13 +11:00
										 |  |  | 					if ((nu->bp->f1 & SELECT) || (nu->bp[nu->pntsu - 1].f1 & SELECT)) { | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 						/* pass */ | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		nu = nu->next; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (nu) | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 		return merge_nurb(C, op); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* find both nurbs and points, nu1 will be put behind nu2 */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = nubase->first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (nu->pntsu == 1) | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			nu->flagu &= ~CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2011-02-15 16:09:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		if ((nu->flagu & CU_NURB_CYCLIC) == 0) {    /* not cyclic */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (nu->type == CU_BEZIER) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, &(nu->bezt[nu->pntsu - 1]))) { | 
					
						
							| 
									
										
										
										
											2014-01-03 01:44:46 +06:00
										 |  |  | 					/* Last point is selected, preferred for nu2 */ | 
					
						
							|  |  |  | 					if (nu2 == NULL) { | 
					
						
							|  |  |  | 						nu2 = nu; | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-01-03 01:44:46 +06:00
										 |  |  | 					else if (nu1 == NULL) { | 
					
						
							|  |  |  | 						nu1 = nu; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						/* Just in case both of first/last CV are selected check
 | 
					
						
							|  |  |  | 						 * whether we really need to switch the direction. | 
					
						
							|  |  |  | 						 */ | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 						if (!BEZT_ISSEL_ANY_HIDDENHANDLES(cu, nu1->bezt)) { | 
					
						
							| 
									
										
										
										
											2014-01-03 01:44:46 +06:00
										 |  |  | 							BKE_nurb_direction_switch(nu1); | 
					
						
							|  |  |  | 							keyData_switchDirectionNurb(cu, nu1); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				else if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, nu->bezt)) { | 
					
						
							| 
									
										
										
										
											2014-01-03 01:44:46 +06:00
										 |  |  | 					/* First point is selected, preferred for nu1 */ | 
					
						
							|  |  |  | 					if (nu1 == NULL) { | 
					
						
							|  |  |  | 						nu1 = nu; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-01-03 01:44:46 +06:00
										 |  |  | 					else if (nu2 == NULL) { | 
					
						
							|  |  |  | 						nu2 = nu; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						/* Just in case both of first/last CV are selected check
 | 
					
						
							|  |  |  | 						 * whether we really need to switch the direction. | 
					
						
							|  |  |  | 						 */ | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 						if (!BEZT_ISSEL_ANY_HIDDENHANDLES(cu, &(nu->bezt[nu2->pntsu - 1]))) { | 
					
						
							| 
									
										
										
										
											2014-01-03 01:44:46 +06:00
										 |  |  | 							BKE_nurb_direction_switch(nu2); | 
					
						
							|  |  |  | 							keyData_switchDirectionNurb(cu, nu2); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			else if (nu->pntsv == 1) { | 
					
						
							| 
									
										
										
										
											2014-01-03 01:44:46 +06:00
										 |  |  | 				/* Same logic as above: if first point is selected spline is
 | 
					
						
							|  |  |  | 				 * preferred for nu1, if last point is selected spline is | 
					
						
							|  |  |  | 				 * preferred for u2u. | 
					
						
							|  |  |  | 				 */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				bp = nu->bp; | 
					
						
							| 
									
										
										
										
											2014-01-03 01:44:46 +06:00
										 |  |  | 				if (bp[nu->pntsu - 1].f1 & SELECT)  { | 
					
						
							|  |  |  | 					if (nu2 == NULL) { | 
					
						
							|  |  |  | 						nu2 = nu; | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-01-03 01:44:46 +06:00
										 |  |  | 					else if (nu1 == NULL) { | 
					
						
							|  |  |  | 						nu1 = nu; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if ((bp->f1 & SELECT) == 0) { | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 							BKE_nurb_direction_switch(nu); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 							keyData_switchDirectionNurb(cu, nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-01-03 01:44:46 +06:00
										 |  |  | 				else if (bp->f1 & SELECT) { | 
					
						
							|  |  |  | 					if (nu1 == NULL) { | 
					
						
							|  |  |  | 						nu1 = nu; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-01-03 01:44:46 +06:00
										 |  |  | 					else if (nu2 == NULL) { | 
					
						
							|  |  |  | 						nu2 = nu; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if ((bp[nu->pntsu - 1].f1 & SELECT) == 0) { | 
					
						
							|  |  |  | 							BKE_nurb_direction_switch(nu); | 
					
						
							|  |  |  | 							keyData_switchDirectionNurb(cu, nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-01-03 01:44:46 +06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (nu1 && nu2) { | 
					
						
							|  |  |  | 			/* Got second spline, no need to loop over rest of the splines. */ | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	if ((nu1 && nu2) && (nu1 != nu2)) { | 
					
						
							|  |  |  | 		if (nu1->type == nu2->type) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (nu1->type == CU_BEZIER) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				BezTriple *bezt = (BezTriple *)MEM_mallocN((nu1->pntsu + nu2->pntsu) * sizeof(BezTriple), "addsegmentN"); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				ED_curve_beztcpy(cu->editnurb, bezt, nu2->bezt, nu2->pntsu); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				ED_curve_beztcpy(cu->editnurb, bezt + nu2->pntsu, nu1->bezt, nu1->pntsu); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				MEM_freeN(nu1->bezt); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				nu1->bezt = bezt; | 
					
						
							|  |  |  | 				nu1->pntsu += nu2->pntsu; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				BLI_remlink(nubase, nu2); | 
					
						
							| 
									
										
										
										
											2014-04-29 19:04:31 +06:00
										 |  |  | 				keyIndex_delNurb(cu->editnurb, nu2); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				BKE_nurb_free(nu2); nu2 = NULL; | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 				BKE_nurb_handles_calc(nu1); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				bp = (BPoint *)MEM_mallocN((nu1->pntsu + nu2->pntsu) * sizeof(BPoint), "addsegmentN2"); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				ED_curve_bpcpy(cu->editnurb, bp, nu2->bp, nu2->pntsu); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				ED_curve_bpcpy(cu->editnurb, bp + nu2->pntsu, nu1->bp, nu1->pntsu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				MEM_freeN(nu1->bp); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				nu1->bp = bp; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-03 21:03:39 +00:00
										 |  |  | 				/* a = nu1->pntsu + nu1->orderu; */ /* UNUSED */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				nu1->pntsu += nu2->pntsu; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 				BLI_remlink(nubase, nu2); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* now join the knots */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (nu1->type == CU_NURBS) { | 
					
						
							| 
									
										
										
										
											2012-06-24 11:27:28 +00:00
										 |  |  | 					if (nu1->knotsu != NULL) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						MEM_freeN(nu1->knotsu); | 
					
						
							| 
									
										
										
										
											2012-06-24 11:27:28 +00:00
										 |  |  | 						nu1->knotsu = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2012-06-24 11:27:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					BKE_nurb_knot_calc_u(nu1); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-04-29 19:04:31 +06:00
										 |  |  | 				keyIndex_delNurb(cu->editnurb, nu2); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				BKE_nurb_free(nu2); nu2 = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 			BKE_curve_nurb_active_set(cu, nu1);   /* for selected */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			ok = 1; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-24 19:24:52 +11:00
										 |  |  | 	else if ((nu1 && !nu2) || (!nu1 && nu2)) { | 
					
						
							|  |  |  | 		if (nu2) { | 
					
						
							|  |  |  | 			SWAP(Nurb *, nu1, nu2); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		if (!(nu1->flagu & CU_NURB_CYCLIC) && nu1->pntsu > 1) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 			if (nu1->type == CU_BEZIER && BEZT_ISSEL_ANY_HIDDENHANDLES(cu, nu1->bezt) && | 
					
						
							|  |  |  | 			    BEZT_ISSEL_ANY_HIDDENHANDLES(cu, &nu1->bezt[nu1->pntsu - 1])) | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 				nu1->flagu |= CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 				BKE_nurb_handles_calc(nu1); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				ok = 1; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			else if (nu1->type == CU_NURBS && nu1->bp->f1 & SELECT && (nu1->bp[nu1->pntsu - 1].f1 & SELECT)) { | 
					
						
							|  |  |  | 				nu1->flagu |= CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 				BKE_nurb_knot_calc_u(nu1); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				ok = 1; | 
					
						
							| 
									
										
										
										
											2010-11-21 19:29:08 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-11-21 19:29:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (!ok) { | 
					
						
							| 
									
										
										
										
											2012-10-26 17:32:50 +00:00
										 |  |  | 		BKE_report(op->reports, RPT_ERROR, "Cannot make segment"); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-11-21 19:29:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-16 08:04:12 +00:00
										 |  |  | 	if (ED_curve_updateAnimPaths(obedit->data)) | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2010-11-21 19:29:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | void CURVE_OT_make_segment(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Make Segment"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_make_segment"; | 
					
						
							| 
									
										
										
										
											2012-05-04 15:00:36 +00:00
										 |  |  | 	ot->description = "Join two curves by their selected ends"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = make_segment_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | /***************** pick select from 3d view **********************/ | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-18 12:20:28 +11:00
										 |  |  | bool ED_curve_editnurb_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	Curve *cu = obedit->data; | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	ViewContext vc; | 
					
						
							|  |  |  | 	Nurb *nu; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	BezTriple *bezt = NULL; | 
					
						
							|  |  |  | 	BPoint *bp = NULL; | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 	const void *vert = BKE_curve_vert_active_get(cu); | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 	int location[2]; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	short hand; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-01-26 17:06:28 +00:00
										 |  |  | 	view3d_operator_needs_opengl(C); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	view3d_set_viewcontext(C, &vc); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	location[0] = mval[0]; | 
					
						
							|  |  |  | 	location[1] = mval[1]; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-08 23:24:16 +10:00
										 |  |  | 	if (ED_curve_pick_vert(&vc, 1, location, &nu, &bezt, &bp, &hand)) { | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 		if (extend) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (bezt) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				if (hand == 1) { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 					select_beztriple(bezt, SELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					if (hand == 0) bezt->f1 |= SELECT; | 
					
						
							|  |  |  | 					else bezt->f3 |= SELECT; | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-07-09 14:52:01 +10:00
										 |  |  | 				BKE_curve_nurb_vert_active_set(cu, nu, bezt); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 				select_bpoint(bp, SELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2015-07-09 14:52:01 +10:00
										 |  |  | 				BKE_curve_nurb_vert_active_set(cu, nu, bp); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 		else if (deselect) { | 
					
						
							|  |  |  | 			if (bezt) { | 
					
						
							|  |  |  | 				if (hand == 1) { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 					select_beztriple(bezt, DESELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 					if (bezt == vert) cu->actvert = CU_ACT_NONE; | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else if (hand == 0) { | 
					
						
							|  |  |  | 					bezt->f1 &= ~SELECT; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					bezt->f3 &= ~SELECT; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 				select_bpoint(bp, DESELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 				if (bp == vert) cu->actvert = CU_ACT_NONE; | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (toggle) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (bezt) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				if (hand == 1) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					if (bezt->f2 & SELECT) { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 						select_beztriple(bezt, DESELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 						if (bezt == vert) cu->actvert = CU_ACT_NONE; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 						select_beztriple(bezt, SELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 						BKE_curve_nurb_vert_active_set(cu, nu, bezt); | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				else if (hand == 0) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					bezt->f1 ^= SELECT; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					bezt->f3 ^= SELECT; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (bp->f1 & SELECT) { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 					select_bpoint(bp, DESELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 					if (bp == vert) cu->actvert = CU_ACT_NONE; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 					select_bpoint(bp, SELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 					BKE_curve_nurb_vert_active_set(cu, nu, bp); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2013-09-16 00:03:33 +00:00
										 |  |  | 			BKE_nurbList_flag_set(editnurb, 0); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 			if (bezt) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (hand == 1) { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 					select_beztriple(bezt, SELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					if (hand == 0) bezt->f1 |= SELECT; | 
					
						
							|  |  |  | 					else bezt->f3 |= SELECT; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-07-09 14:52:01 +10:00
										 |  |  | 				BKE_curve_nurb_vert_active_set(cu, nu, bezt); | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 				select_bpoint(bp, SELECT, SELECT, HIDDEN); | 
					
						
							| 
									
										
										
										
											2015-07-09 14:52:01 +10:00
										 |  |  | 				BKE_curve_nurb_vert_active_set(cu, nu, bp); | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 		if (nu != BKE_curve_nurb_active_get(cu)) { | 
					
						
							|  |  |  | 			cu->actvert = CU_ACT_NONE; | 
					
						
							|  |  |  | 			BKE_curve_nurb_active_set(cu, nu); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); | 
					
						
							| 
									
										
										
										
											2009-11-24 04:59:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-19 23:17:44 +00:00
										 |  |  | 		return true; | 
					
						
							| 
									
										
										
										
											2009-11-24 04:59:52 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-03-19 23:17:44 +00:00
										 |  |  | 	return false; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | /******************** spin operator ***********************/ | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-29 16:18:39 +00:00
										 |  |  | /* 'cent' is in object space and 'dvec' in worldspace.
 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-09-16 00:03:33 +00:00
										 |  |  | bool ed_editnurb_spin(float viewmat[4][4], Object *obedit, const float axis[3], const float cent[3]) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Curve *cu = (Curve *)obedit->data; | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu; | 
					
						
							| 
									
										
										
										
											2013-11-24 21:25:05 +11:00
										 |  |  | 	float cmat[3][3], tmat[3][3], imat[3][3]; | 
					
						
							| 
									
										
										
										
											2010-01-12 01:50:34 +00:00
										 |  |  | 	float bmat[3][3], rotmat[3][3], scalemat1[3][3], scalemat2[3][3]; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	float persmat[3][3], persinv[3][3]; | 
					
						
							| 
									
										
										
										
											2013-09-16 00:03:33 +00:00
										 |  |  | 	bool ok, changed = false; | 
					
						
							|  |  |  | 	int a; | 
					
						
							| 
									
										
										
										
											2010-09-29 15:19:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-30 05:26:36 +00:00
										 |  |  | 	copy_m3_m4(persmat, viewmat); | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | 	invert_m3_m3(persinv, persmat); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* imat and center and size */ | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | 	copy_m3_m4(bmat, obedit->obmat); | 
					
						
							|  |  |  | 	invert_m3_m3(imat, bmat); | 
					
						
							| 
									
										
										
										
											2010-09-30 05:26:36 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-11-24 21:25:05 +11:00
										 |  |  | 	axis_angle_to_mat3(cmat, axis, M_PI / 4.0); | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | 	mul_m3_m3m3(tmat, cmat, bmat); | 
					
						
							|  |  |  | 	mul_m3_m3m3(rotmat, imat, tmat); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | 	unit_m3(scalemat1); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	scalemat1[0][0] = M_SQRT2; | 
					
						
							|  |  |  | 	scalemat1[1][1] = M_SQRT2; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-29 15:47:02 +00:00
										 |  |  | 	mul_m3_m3m3(tmat, persmat, bmat); | 
					
						
							|  |  |  | 	mul_m3_m3m3(cmat, scalemat1, tmat); | 
					
						
							|  |  |  | 	mul_m3_m3m3(tmat, persinv, cmat); | 
					
						
							|  |  |  | 	mul_m3_m3m3(scalemat1, imat, tmat); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | 	unit_m3(scalemat2); | 
					
						
							| 
									
										
										
										
											2012-04-29 15:47:02 +00:00
										 |  |  | 	scalemat2[0][0] /= (float)M_SQRT2; | 
					
						
							|  |  |  | 	scalemat2[1][1] /= (float)M_SQRT2; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-29 15:47:02 +00:00
										 |  |  | 	mul_m3_m3m3(tmat, persmat, bmat); | 
					
						
							|  |  |  | 	mul_m3_m3m3(cmat, scalemat2, tmat); | 
					
						
							|  |  |  | 	mul_m3_m3m3(tmat, persinv, cmat); | 
					
						
							|  |  |  | 	mul_m3_m3m3(scalemat2, imat, tmat); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-16 00:03:33 +00:00
										 |  |  | 	ok = true; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (a = 0; a < 7; a++) { | 
					
						
							| 
									
										
										
										
											2014-10-28 18:39:43 +01:00
										 |  |  | 		ok = ed_editnurb_extrude_flag(cu->editnurb, SELECT); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-16 00:03:33 +00:00
										 |  |  | 		if (ok == false) | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 			return changed; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-16 00:03:33 +00:00
										 |  |  | 		changed = true; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-30 05:26:36 +00:00
										 |  |  | 		rotateflagNurb(editnurb, SELECT, cent, rotmat); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-16 00:03:33 +00:00
										 |  |  | 		if ((a & 1) == 0) { | 
					
						
							| 
									
										
										
										
											2010-09-30 05:26:36 +00:00
										 |  |  | 			rotateflagNurb(editnurb, SELECT, cent, scalemat1); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			weightflagNurb(editnurb, SELECT, 0.25 * M_SQRT2); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-09-30 05:26:36 +00:00
										 |  |  | 		else { | 
					
						
							|  |  |  | 			rotateflagNurb(editnurb, SELECT, cent, scalemat2); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			weightflagNurb(editnurb, SELECT, 4.0 / M_SQRT2); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (ok) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 			if (ED_curve_nurb_select_check(cu, nu)) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				nu->orderv = 4; | 
					
						
							| 
									
										
										
											
												merge own commits into render branch into trunk since 27560
27562, 27570, 27571, 27574, 27576, 27577, 27579, 27590, 27591, 27594, 27595, 27596, 27599, 27605, 27611, 27612, 27613, 27614, 27623
											
										 
											2010-03-20 16:41:01 +00:00
										 |  |  | 				nu->flagv |= CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 				BKE_nurb_knot_calc_v(nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return changed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int spin_exec(bContext *C, wmOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	RegionView3D *rv3d = ED_view3d_context_rv3d(C); | 
					
						
							| 
									
										
										
										
											2011-01-03 10:47:36 +00:00
										 |  |  | 	float cent[3], axis[3], viewmat[4][4]; | 
					
						
							| 
									
										
										
										
											2010-01-12 01:50:34 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	RNA_float_get_array(op->ptr, "center", cent); | 
					
						
							|  |  |  | 	RNA_float_get_array(op->ptr, "axis", axis); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-09-29 15:19:16 +00:00
										 |  |  | 	invert_m4_m4(obedit->imat, obedit->obmat); | 
					
						
							|  |  |  | 	mul_m4_v3(obedit->imat, cent); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (rv3d) | 
					
						
							| 
									
										
										
										
											2011-01-03 10:47:36 +00:00
										 |  |  | 		copy_m4_m4(viewmat, rv3d->viewmat); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		unit_m4(viewmat); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-09-16 00:03:33 +00:00
										 |  |  | 	if (!ed_editnurb_spin(viewmat, obedit, axis, cent)) { | 
					
						
							| 
									
										
										
										
											2012-10-26 17:32:50 +00:00
										 |  |  | 		BKE_report(op->reports, RPT_ERROR, "Cannot spin"); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-16 08:04:12 +00:00
										 |  |  | 	if (ED_curve_updateAnimPaths(obedit->data)) | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-13 09:03:46 +00:00
										 |  |  | static int spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | 
					
						
							| 
									
										
										
										
											2010-01-12 01:50:34 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	Scene *scene = CTX_data_scene(C); | 
					
						
							|  |  |  | 	View3D *v3d = CTX_wm_view3d(C); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	RegionView3D *rv3d = ED_view3d_context_rv3d(C); | 
					
						
							|  |  |  | 	float axis[3] = {0.0f, 0.0f, 1.0f}; | 
					
						
							| 
									
										
										
										
											2011-01-03 10:47:36 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (rv3d) | 
					
						
							| 
									
										
										
										
											2011-01-03 10:47:36 +00:00
										 |  |  | 		copy_v3_v3(axis, rv3d->viewinv[2]); | 
					
						
							| 
									
										
										
										
											2010-01-12 01:50:34 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-10-26 04:07:18 +00:00
										 |  |  | 	RNA_float_set_array(op->ptr, "center", ED_view3d_cursor3d_get(scene, v3d)); | 
					
						
							| 
									
										
										
										
											2011-01-03 10:47:36 +00:00
										 |  |  | 	RNA_float_set_array(op->ptr, "axis", axis); | 
					
						
							| 
									
										
										
										
											2010-01-12 01:50:34 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	return spin_exec(C, op); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | void CURVE_OT_spin(wmOperatorType *ot) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Spin"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_spin"; | 
					
						
							| 
									
										
										
										
											2012-05-04 15:00:36 +00:00
										 |  |  | 	ot->description = "Extrude selected boundary row around pivot point and current view axis"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = spin_exec; | 
					
						
							| 
									
										
										
										
											2010-01-12 01:50:34 +00:00
										 |  |  | 	ot->invoke = spin_invoke; | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->poll = ED_operator_editsurf; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2010-01-12 01:50:34 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2015-06-21 16:06:44 +02:00
										 |  |  | 	RNA_def_float_vector_xyz(ot->srna, "center", 3, NULL, -OBJECT_ADD_SIZE_MAXF, OBJECT_ADD_SIZE_MAXF, | 
					
						
							|  |  |  | 	                         "Center", "Center in global view space", -1000.0f, 1000.0f); | 
					
						
							|  |  |  | 	RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -1.0f, 1.0f); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | /***************** extrude vertex operator **********************/ | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | static bool ed_editcurve_extrude(Curve *cu, EditNurb *editnurb) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	Nurb *nu = NULL; | 
					
						
							|  |  |  | 	Nurb *nu_last = NULL; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	bool changed = false; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	Nurb *cu_actnu; | 
					
						
							|  |  |  | 	union { | 
					
						
							|  |  |  | 		BezTriple *bezt; | 
					
						
							|  |  |  | 		BPoint    *bp; | 
					
						
							|  |  |  | 		void      *p; | 
					
						
							|  |  |  | 	} cu_actvert; | 
					
						
							| 
									
										
										
										
											2011-02-14 17:17:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 18:22:08 +11:00
										 |  |  | 	if (BLI_listbase_is_empty(&editnurb->nurbs)) { | 
					
						
							|  |  |  | 		return changed; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	BKE_curve_nurb_vert_active_get(cu, &cu_actnu, &cu_actvert.p); | 
					
						
							|  |  |  | 	BKE_curve_nurb_vert_active_set(cu, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	/* first pass (endpoints) */ | 
					
						
							|  |  |  | 	for (nu = editnurb->nurbs.first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2011-05-07 02:48:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 		if ((nu->flagu & CU_NURB_CYCLIC) && (nu->pntsu > 1)) { | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-05-07 02:48:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 		if (nu->type == CU_BEZIER) { | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 			/* Check to see if the first bezier point is selected */ | 
					
						
							|  |  |  | 			if (nu->pntsu > 0 && nu->bezt != NULL) { | 
					
						
							|  |  |  | 				BezTriple *nu_bezt_old = nu->bezt; | 
					
						
							|  |  |  | 				BezTriple *bezt = nu->bezt; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt)) { | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 					BezTriple *bezt_new; | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 					BEZT_DESEL_ALL(bezt); | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 					bezt_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BezTriple), __func__); | 
					
						
							|  |  |  | 					ED_curve_beztcpy(editnurb, bezt_new + 1, bezt, nu->pntsu); | 
					
						
							|  |  |  | 					*bezt_new = *bezt; | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 					MEM_freeN(nu->bezt); | 
					
						
							|  |  |  | 					nu->bezt = bezt_new; | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 					nu->pntsu += 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (ARRAY_HAS_ITEM(cu_actvert.bezt, nu_bezt_old, nu->pntsu - 1)) { | 
					
						
							|  |  |  | 						cu_actvert.bezt = (cu_actvert.bezt == bezt) ? | 
					
						
							|  |  |  | 						                  bezt_new : &nu->bezt[(cu_actvert.bezt - nu_bezt_old) + 1]; | 
					
						
							|  |  |  | 						BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bezt); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 					BEZT_SEL_ALL(bezt_new); | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 					changed = true; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 			/* Check to see if the last bezier point is selected */ | 
					
						
							|  |  |  | 			if (nu->pntsu > 1) { | 
					
						
							|  |  |  | 				BezTriple *nu_bezt_old = nu->bezt; | 
					
						
							|  |  |  | 				BezTriple *bezt = &nu->bezt[nu->pntsu - 1]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt)) { | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 					BezTriple *bezt_new; | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 					BEZT_DESEL_ALL(bezt); | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					bezt_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BezTriple), __func__); | 
					
						
							|  |  |  | 					ED_curve_beztcpy(editnurb, bezt_new, nu->bezt, nu->pntsu); | 
					
						
							|  |  |  | 					bezt_new[nu->pntsu] = *bezt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					MEM_freeN(nu->bezt); | 
					
						
							|  |  |  | 					nu->bezt = bezt_new; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					bezt_new += nu->pntsu; | 
					
						
							|  |  |  | 					nu->pntsu += 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (ARRAY_HAS_ITEM(cu_actvert.bezt, nu_bezt_old, nu->pntsu - 1)) { | 
					
						
							|  |  |  | 						cu_actvert.bezt = (cu_actvert.bezt == bezt) ? | 
					
						
							|  |  |  | 						                  bezt_new : &nu->bezt[cu_actvert.bezt - nu_bezt_old]; | 
					
						
							|  |  |  | 						BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bezt); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 					BEZT_SEL_ALL(bezt_new); | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 					changed = true; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 			/* Check to see if the first bpoint is selected */ | 
					
						
							|  |  |  | 			if (nu->pntsu > 0 && nu->bp != NULL) { | 
					
						
							|  |  |  | 				BPoint *nu_bp_old = nu->bp; | 
					
						
							|  |  |  | 				BPoint *bp = nu->bp; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 				if (bp->f1 & SELECT) { | 
					
						
							|  |  |  | 					BPoint *bp_new; | 
					
						
							|  |  |  | 					bp->f1 &= ~SELECT; | 
					
						
							| 
									
										
										
										
											2012-04-02 10:20:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 					bp_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BPoint), __func__); | 
					
						
							|  |  |  | 					ED_curve_bpcpy(editnurb, bp_new + 1, bp, nu->pntsu); | 
					
						
							|  |  |  | 					*bp_new = *bp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					MEM_freeN(nu->bp); | 
					
						
							|  |  |  | 					nu->bp = bp_new; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					nu->pntsu += 1; | 
					
						
							|  |  |  | 					BKE_nurb_knot_calc_u(nu); | 
					
						
							| 
									
										
										
										
											2012-04-02 10:20:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 					if (ARRAY_HAS_ITEM(cu_actvert.bp, nu_bp_old, nu->pntsu - 1)) { | 
					
						
							|  |  |  | 						cu_actvert.bp = (cu_actvert.bp == bp) ? | 
					
						
							|  |  |  | 						                 bp_new : &nu->bp[(cu_actvert.bp - nu_bp_old) + 1]; | 
					
						
							|  |  |  | 						BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bp); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					bp_new->f1 |= SELECT; | 
					
						
							|  |  |  | 					changed = true; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* Check to see if the last bpoint is selected */ | 
					
						
							| 
									
										
										
										
											2012-04-02 10:20:10 +00:00
										 |  |  | 			if (nu->pntsu > 1) { | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 				BPoint *nu_bp_old = nu->bp; | 
					
						
							|  |  |  | 				BPoint *bp = &nu->bp[nu->pntsu - 1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (bp->f1 & SELECT) { | 
					
						
							|  |  |  | 					BPoint *bp_new; | 
					
						
							|  |  |  | 					bp->f1 &= ~SELECT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					bp_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BPoint), __func__); | 
					
						
							|  |  |  | 					ED_curve_bpcpy(editnurb, bp_new, nu->bp, nu->pntsu); | 
					
						
							|  |  |  | 					bp_new[nu->pntsu] = *bp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					MEM_freeN(nu->bp); | 
					
						
							|  |  |  | 					nu->bp = bp_new; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					bp_new += nu->pntsu; | 
					
						
							|  |  |  | 					nu->pntsu += 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (ARRAY_HAS_ITEM(cu_actvert.bp, nu_bp_old, nu->pntsu - 1)) { | 
					
						
							|  |  |  | 						cu_actvert.bp = (cu_actvert.bp == bp) ? | 
					
						
							|  |  |  | 						                 bp_new : &nu->bp[cu_actvert.bp - nu_bp_old]; | 
					
						
							|  |  |  | 						BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bp); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					BKE_nurb_knot_calc_u(nu); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					bp_new->f1 |= SELECT; | 
					
						
							|  |  |  | 					changed = true; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-04-02 10:20:10 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	/* second pass (interior points) */ | 
					
						
							|  |  |  | 	nu_last = editnurb->nurbs.last; | 
					
						
							|  |  |  | 	for (nu = editnurb->nurbs.first; (nu != nu_last->next); nu = nu->next) { | 
					
						
							|  |  |  | 		int i, i_end; | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 		if ((nu->flagu & CU_NURB_CYCLIC) && (nu->pntsu > 1)) { | 
					
						
							|  |  |  | 			/* all points are interior */ | 
					
						
							|  |  |  | 			i = 0; | 
					
						
							|  |  |  | 			i_end = nu->pntsu; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 			/* skip endpoints */ | 
					
						
							|  |  |  | 			i = 1; | 
					
						
							|  |  |  | 			i_end = nu->pntsu - 1; | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 		if (nu->type == CU_BEZIER) { | 
					
						
							|  |  |  | 			BezTriple *bezt; | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 			for (bezt = &nu->bezt[i]; i < i_end; i++, bezt++) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt)) { | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 					Nurb *nurb_new; | 
					
						
							|  |  |  | 					BezTriple *bezt_new; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 					BEZT_DESEL_ALL(bezt); | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 					nurb_new = BKE_nurb_copy(nu, 1, 1); | 
					
						
							|  |  |  | 					nurb_new->flagu &= ~CU_NURB_CYCLIC; | 
					
						
							|  |  |  | 					BLI_addtail(&editnurb->nurbs, nurb_new); | 
					
						
							|  |  |  | 					bezt_new = nurb_new->bezt; | 
					
						
							|  |  |  | 					ED_curve_beztcpy(editnurb, bezt_new, bezt, 1); | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 					BEZT_SEL_ALL(bezt_new); | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					if (cu_actvert.bezt == bezt || cu_actnu == NULL) { | 
					
						
							|  |  |  | 						BKE_curve_nurb_vert_active_set(cu, nurb_new, bezt_new); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					changed = true; | 
					
						
							| 
									
										
										
										
											2012-04-02 10:20:10 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			BPoint *bp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (bp = &nu->bp[i]; i < i_end; i++, bp++) { | 
					
						
							|  |  |  | 				if (bp->f1 & SELECT) { | 
					
						
							|  |  |  | 					Nurb *nurb_new; | 
					
						
							|  |  |  | 					BPoint *bp_new; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					bp->f1 &= ~SELECT; | 
					
						
							|  |  |  | 					nurb_new = BKE_nurb_copy(nu, 1, 1); | 
					
						
							|  |  |  | 					nurb_new->flagu &= ~CU_NURB_CYCLIC; | 
					
						
							|  |  |  | 					BLI_addtail(&editnurb->nurbs, nurb_new); | 
					
						
							|  |  |  | 					bp_new = nurb_new->bp; | 
					
						
							|  |  |  | 					ED_curve_bpcpy(editnurb, bp_new, bp, 1); | 
					
						
							|  |  |  | 					bp_new->f1 |= SELECT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (cu_actvert.bp == bp || cu_actnu == NULL) { | 
					
						
							|  |  |  | 						BKE_curve_nurb_vert_active_set(cu, nurb_new, bp_new); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 					changed = true; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	if (changed == false) { | 
					
						
							|  |  |  | 		BKE_curve_nurb_vert_active_set(cu, cu_actnu, cu_actvert.p); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	return changed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /***************** add vertex operator **********************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ed_editcurve_addvert(Curve *cu, EditNurb *editnurb, const float location[3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	float minmax[2][3]; | 
					
						
							|  |  |  | 	float temp[3]; | 
					
						
							|  |  |  | 	bool nu_has_select = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bool changed = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	INIT_MINMAX(minmax[0], minmax[1]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (nu = editnurb->nurbs.first; nu; nu = nu->next) { | 
					
						
							|  |  |  | 		int i; | 
					
						
							|  |  |  | 		if (nu->type == CU_BEZIER) { | 
					
						
							|  |  |  | 			BezTriple *bezt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (i = 0, bezt = nu->bezt; i < nu->pntsu; i++, bezt++) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt)) { | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 					minmax_v3v3_v3(UNPACK2(minmax), bezt->vec[1]); | 
					
						
							|  |  |  | 					nu_has_select = true; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 			BPoint *bp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (i = 0, bp = nu->bp; i < nu->pntsu; i++, bp++) { | 
					
						
							|  |  |  | 				if (bp->f1 & SELECT) { | 
					
						
							|  |  |  | 					minmax_v3v3_v3(UNPACK2(minmax), bp->vec); | 
					
						
							|  |  |  | 					nu_has_select = true; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (nu_has_select && ed_editcurve_extrude(cu, editnurb)) { | 
					
						
							|  |  |  | 		float ofs[3], center[3]; | 
					
						
							|  |  |  | 		int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		mid_v3_v3v3(center, minmax[0], minmax[1]); | 
					
						
							|  |  |  | 		sub_v3_v3v3(ofs, location, center); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if ((cu->flag & CU_3D) == 0) { | 
					
						
							|  |  |  | 			ofs[2] = 0.0f; | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 		for (nu = editnurb->nurbs.first; nu; nu = nu->next) { | 
					
						
							|  |  |  | 			if (nu->type == CU_BEZIER) { | 
					
						
							|  |  |  | 				BezTriple *bezt; | 
					
						
							|  |  |  | 				for (i = 0, bezt = nu->bezt; i < nu->pntsu; i++, bezt++) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 					if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt)) { | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 						add_v3_v3(bezt->vec[0], ofs); | 
					
						
							|  |  |  | 						add_v3_v3(bezt->vec[1], ofs); | 
					
						
							|  |  |  | 						add_v3_v3(bezt->vec[2], ofs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if (((nu->flagu & CU_NURB_CYCLIC) == 0) && | 
					
						
							|  |  |  | 						    (i == 0 || i == nu->pntsu - 1)) | 
					
						
							|  |  |  | 						{ | 
					
						
							|  |  |  | 							BKE_nurb_handle_calc_simple_auto(nu, bezt); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 				BPoint *bp; | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 				for (i = 0, bp = nu->bp; i < nu->pntsu; i++, bp++) { | 
					
						
							|  |  |  | 					if (bp->f1 & SELECT) { | 
					
						
							|  |  |  | 						add_v3_v3(bp->vec, ofs); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		changed = true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		/* nothing selected: create a new curve */ | 
					
						
							|  |  |  | 		nu = BKE_curve_nurb_active_get(cu); | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 		if (!nu || nu->type == CU_BEZIER) { | 
					
						
							|  |  |  | 			Nurb *nurb_new; | 
					
						
							|  |  |  | 			BezTriple *bezt_new; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (nu) { | 
					
						
							|  |  |  | 				nurb_new = BKE_nurb_copy(nu, 1, 1); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 				nurb_new = MEM_callocN(sizeof(Nurb), "BLI_editcurve_addvert new_bezt_nurb 2"); | 
					
						
							|  |  |  | 				nurb_new->type = CU_BEZIER; | 
					
						
							|  |  |  | 				nurb_new->resolu = cu->resolu; | 
					
						
							|  |  |  | 				nurb_new->orderu = 4; | 
					
						
							|  |  |  | 				nurb_new->flag |= CU_SMOOTH; | 
					
						
							|  |  |  | 				BKE_nurb_bezierPoints_add(nurb_new, 1); | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 			BLI_addtail(&editnurb->nurbs, nurb_new); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 			bezt_new = nurb_new->bezt; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 			BEZT_SEL_ALL(bezt_new); | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			bezt_new->h1 = HD_AUTO; | 
					
						
							|  |  |  | 			bezt_new->h2 = HD_AUTO; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			temp[0] = 1.0f; | 
					
						
							|  |  |  | 			temp[1] = 0.0f; | 
					
						
							|  |  |  | 			temp[2] = 0.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			copy_v3_v3(bezt_new->vec[1], location); | 
					
						
							|  |  |  | 			sub_v3_v3v3(bezt_new->vec[0], bezt_new->vec[1], temp); | 
					
						
							|  |  |  | 			add_v3_v3v3(bezt_new->vec[2], bezt_new->vec[1], temp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			changed = true; | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 			Nurb *nurb_new; | 
					
						
							|  |  |  | 			BPoint *bp_new; | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 				nurb_new = MEM_callocN(sizeof(Nurb), __func__); | 
					
						
							|  |  |  | 				nurb_new->type = CU_POLY; | 
					
						
							|  |  |  | 				nurb_new->resolu = cu->resolu; | 
					
						
							|  |  |  | 				nurb_new->flag |= CU_SMOOTH; | 
					
						
							|  |  |  | 				nurb_new->orderu = 4; | 
					
						
							|  |  |  | 				BKE_nurb_points_add(nurb_new, 1); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			BLI_addtail(&editnurb->nurbs, nurb_new); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 			bp_new = nurb_new->bp; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 			bp_new->f1 |= SELECT; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 			copy_v3_v3(bp_new->vec, location); | 
					
						
							|  |  |  | 			bp_new->vec[3] = 1.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			BKE_nurb_knot_calc_u(nurb_new); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			changed = true; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-12-19 19:22:17 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	return changed; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int add_vertex_exec(bContext *C, wmOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	Curve *cu = obedit->data; | 
					
						
							|  |  |  | 	EditNurb *editnurb = cu->editnurb; | 
					
						
							| 
									
										
										
										
											2009-02-13 17:37:01 +00:00
										 |  |  | 	float location[3]; | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	float imat[4][4]; | 
					
						
							| 
									
										
										
										
											2009-02-13 17:37:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	RNA_float_get_array(op->ptr, "location", location); | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	invert_m4_m4(imat, obedit->obmat); | 
					
						
							|  |  |  | 	mul_m4_v3(imat, location); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ed_editcurve_addvert(cu, editnurb, location)) { | 
					
						
							|  |  |  | 		if (ED_curve_updateAnimPaths(obedit->data)) { | 
					
						
							|  |  |  | 			WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							|  |  |  | 		DAG_id_tag_update(obedit->data, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return OPERATOR_FINISHED; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-13 09:03:46 +00:00
										 |  |  | static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-06-10 03:56:50 +00:00
										 |  |  | 	ViewContext vc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	view3d_set_viewcontext(C, &vc); | 
					
						
							| 
									
										
										
										
											2009-02-13 17:37:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-10 03:56:50 +00:00
										 |  |  | 	if (vc.rv3d && !RNA_struct_property_is_set(op->ptr, "location")) { | 
					
						
							| 
									
										
										
										
											2011-05-07 02:48:14 +00:00
										 |  |  | 		Curve *cu; | 
					
						
							|  |  |  | 		float location[3]; | 
					
						
							| 
									
										
										
										
											2013-06-10 03:56:50 +00:00
										 |  |  | 		const bool use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) && | 
					
						
							|  |  |  | 		                       (vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE)); | 
					
						
							| 
									
										
										
										
											2011-05-07 02:48:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Nurb *nu; | 
					
						
							|  |  |  | 		BezTriple *bezt; | 
					
						
							|  |  |  | 		BPoint *bp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		cu = vc.obedit->data; | 
					
						
							| 
									
										
										
										
											2011-05-07 02:48:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 		findselectedNurbvert(cu, &nu, &bezt, &bp); | 
					
						
							| 
									
										
										
										
											2011-05-07 02:48:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (bezt) { | 
					
						
							| 
									
										
										
										
											2011-05-07 02:48:14 +00:00
										 |  |  | 			mul_v3_m4v3(location, vc.obedit->obmat, bezt->vec[1]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (bp) { | 
					
						
							|  |  |  | 			mul_v3_m4v3(location, vc.obedit->obmat, bp->vec); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2013-10-26 04:07:18 +00:00
										 |  |  | 			copy_v3_v3(location, ED_view3d_cursor3d_get(vc.scene, vc.v3d)); | 
					
						
							| 
									
										
										
										
											2011-05-07 02:48:14 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-26 02:37:29 +00:00
										 |  |  | 		ED_view3d_win_to_3d_int(vc.ar, location, event->mval, location); | 
					
						
							| 
									
										
										
										
											2013-06-10 03:56:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (use_proj) { | 
					
						
							|  |  |  | 			const float mval[2] = {UNPACK2(event->mval)}; | 
					
						
							|  |  |  | 			float no_dummy[3]; | 
					
						
							|  |  |  | 			float dist_px_dummy; | 
					
						
							| 
									
										
										
										
											2014-06-18 18:20:55 +03:00
										 |  |  | 			snapObjectsContext(C, mval, &dist_px_dummy, location, no_dummy, SNAP_NOT_OBEDIT); | 
					
						
							| 
									
										
										
										
											2013-06-10 03:56:50 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-13 17:37:01 +00:00
										 |  |  | 		RNA_float_set_array(op->ptr, "location", location); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return add_vertex_exec(C, op); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-12 22:43:07 +00:00
										 |  |  | void CURVE_OT_vertex_add(wmOperatorType *ot) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Add Vertex"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_vertex_add"; | 
					
						
							| 
									
										
										
										
											2012-05-04 15:00:36 +00:00
										 |  |  | 	ot->description = "Add a new control point (linked to only selected end-curve one, if any)"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = add_vertex_exec; | 
					
						
							|  |  |  | 	ot->invoke = add_vertex_invoke; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-02-13 17:37:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* properties */ | 
					
						
							| 
									
										
										
										
											2015-06-21 16:06:44 +02:00
										 |  |  | 	RNA_def_float_vector_xyz(ot->srna, "location", 3, NULL, -OBJECT_ADD_SIZE_MAXF, OBJECT_ADD_SIZE_MAXF, | 
					
						
							|  |  |  | 	                         "Location", "Location to add new vertex at", -1.0e4f, 1.0e4f); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | /***************** extrude operator **********************/ | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | static int curve_extrude_exec(bContext *C, wmOperator *UNUSED(op)) | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	Curve *cu = obedit->data; | 
					
						
							|  |  |  | 	EditNurb *editnurb = cu->editnurb; | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	bool changed = false; | 
					
						
							|  |  |  | 	bool as_curve = false; | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	/* first test: curve? */ | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	if (obedit->type != OB_CURVE) { | 
					
						
							|  |  |  | 		Nurb *nu; | 
					
						
							|  |  |  | 		for (nu = editnurb->nurbs.first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 			if ((nu->pntsv == 1) && | 
					
						
							|  |  |  | 			    (ED_curve_nurb_select_count(cu, nu) == 1)) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 				as_curve = true; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	if (obedit->type == OB_CURVE || as_curve) { | 
					
						
							|  |  |  | 		changed = ed_editcurve_extrude(cu, editnurb); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 		changed = ed_editnurb_extrude_flag(editnurb, SELECT); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-12-06 17:20:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	if (changed) { | 
					
						
							|  |  |  | 		if (ED_curve_updateAnimPaths(obedit->data)) { | 
					
						
							|  |  |  | 			WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							|  |  |  | 		DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | void CURVE_OT_extrude(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Extrude"; | 
					
						
							| 
									
										
										
										
											2012-05-13 09:13:47 +00:00
										 |  |  | 	ot->description = "Extrude selected control point(s)"; | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->idname = "CURVE_OT_extrude"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2015-01-26 20:55:41 +11:00
										 |  |  | 	ot->exec = curve_extrude_exec; | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* to give to transform */ | 
					
						
							| 
									
										
										
										
											2011-04-01 08:51:12 +00:00
										 |  |  | 	RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", ""); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | /***************** make cyclic operator **********************/ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | static int toggle_cyclic_exec(bContext *C, wmOperator *op) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	Curve *cu = obedit->data; | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	BezTriple *bezt; | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	int a, direction = RNA_enum_get(op->ptr, "direction"); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							|  |  |  | 		if (nu->pntsu > 1 || nu->pntsv > 1) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (nu->type == CU_POLY) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				a = nu->pntsu; | 
					
						
							|  |  |  | 				bp = nu->bp; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				while (a--) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					if (bp->f1 & SELECT) { | 
					
						
							| 
									
										
										
											
												merge own commits into render branch into trunk since 27560
27562, 27570, 27571, 27574, 27576, 27577, 27579, 27590, 27591, 27594, 27595, 27596, 27599, 27605, 27611, 27612, 27613, 27614, 27623
											
										 
											2010-03-20 16:41:01 +00:00
										 |  |  | 						nu->flagu ^= CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					bp++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			else if (nu->type == CU_BEZIER) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				a = nu->pntsu; | 
					
						
							|  |  |  | 				bezt = nu->bezt; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				while (a--) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 					if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt)) { | 
					
						
							| 
									
										
										
											
												merge own commits into render branch into trunk since 27560
27562, 27570, 27571, 27574, 27576, 27577, 27579, 27590, 27591, 27594, 27595, 27596, 27599, 27605, 27611, 27612, 27613, 27614, 27623
											
										 
											2010-03-20 16:41:01 +00:00
										 |  |  | 						nu->flagu ^= CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					bezt++; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 				BKE_nurb_handles_calc(nu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			else if (nu->pntsv == 1 && nu->type == CU_NURBS) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				if (nu->knotsu) { /* if check_valid_nurb_u fails the knotsu can be NULL */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					a = nu->pntsu; | 
					
						
							|  |  |  | 					bp = nu->bp; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					while (a--) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						if (bp->f1 & SELECT) { | 
					
						
							| 
									
										
										
											
												merge own commits into render branch into trunk since 27560
27562, 27570, 27571, 27574, 27576, 27577, 27579, 27590, 27591, 27594, 27595, 27596, 27599, 27605, 27611, 27612, 27613, 27614, 27623
											
										 
											2010-03-20 16:41:01 +00:00
										 |  |  | 							nu->flagu ^= CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							BKE_nurb_knot_calc_u(nu);   /* 1==u  type is ignored for cyclic curves */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 							break; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						bp++; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			else if (nu->type == CU_NURBS) { | 
					
						
							|  |  |  | 				a = nu->pntsu * nu->pntsv; | 
					
						
							|  |  |  | 				bp = nu->bp; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				while (a--) { | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					if (bp->f1 & SELECT) { | 
					
						
							|  |  |  | 						if (direction == 0 && nu->pntsu > 1) { | 
					
						
							| 
									
										
										
											
												merge own commits into render branch into trunk since 27560
27562, 27570, 27571, 27574, 27576, 27577, 27579, 27590, 27591, 27594, 27595, 27596, 27599, 27605, 27611, 27612, 27613, 27614, 27623
											
										 
											2010-03-20 16:41:01 +00:00
										 |  |  | 							nu->flagu ^= CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 							BKE_nurb_knot_calc_u(nu);   /* 1==u  type is ignored for cyclic curves */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						if (direction == 1 && nu->pntsv > 1) { | 
					
						
							| 
									
										
										
											
												merge own commits into render branch into trunk since 27560
27562, 27570, 27571, 27574, 27576, 27577, 27579, 27590, 27591, 27594, 27595, 27596, 27599, 27605, 27611, 27612, 27613, 27614, 27623
											
										 
											2010-03-20 16:41:01 +00:00
										 |  |  | 							nu->flagv ^= CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 							BKE_nurb_knot_calc_v(nu);   /* 2==v  type is ignored for cyclic curves */ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					bp++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-13 09:03:46 +00:00
										 |  |  | static int toggle_cyclic_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-04-22 18:39:44 +00:00
										 |  |  | 	uiPopupMenu *pup; | 
					
						
							|  |  |  | 	uiLayout *layout; | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (obedit->type == OB_SURF) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							|  |  |  | 			if (nu->pntsu > 1 || nu->pntsv > 1) { | 
					
						
							|  |  |  | 				if (nu->type == CU_NURBS) { | 
					
						
							| 
									
										
										
										
											2014-11-09 21:20:40 +01:00
										 |  |  | 					pup = UI_popup_menu_begin(C, IFACE_("Direction"), ICON_NONE); | 
					
						
							|  |  |  | 					layout = UI_popup_menu_layout(pup); | 
					
						
							| 
									
										
										
										
											2011-02-15 16:37:44 +00:00
										 |  |  | 					uiItemsEnumO(layout, op->type->idname, "direction"); | 
					
						
							| 
									
										
										
										
											2014-11-09 21:20:40 +01:00
										 |  |  | 					UI_popup_menu_end(C, pup); | 
					
						
							| 
									
										
										
										
											2014-10-28 17:51:06 +01:00
										 |  |  | 					return OPERATOR_INTERFACE; | 
					
						
							| 
									
										
										
										
											2011-02-15 16:37:44 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-02-15 16:37:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 	return toggle_cyclic_exec(C, op); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-29 02:15:13 +00:00
										 |  |  | void CURVE_OT_cyclic_toggle(wmOperatorType *ot) | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	static EnumPropertyItem direction_items[] = { | 
					
						
							| 
									
										
										
										
											2009-06-16 00:52:21 +00:00
										 |  |  | 		{0, "CYCLIC_U", 0, "Cyclic U", ""}, | 
					
						
							|  |  |  | 		{1, "CYCLIC_V", 0, "Cyclic V", ""}, | 
					
						
							| 
									
										
										
										
											2012-06-05 21:54:21 +00:00
										 |  |  | 		{0, NULL, 0, NULL, NULL} | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Toggle Cyclic"; | 
					
						
							| 
									
										
										
										
											2011-04-04 20:31:01 +00:00
										 |  |  | 	ot->description = "Make active spline closed/opened loop"; | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->idname = "CURVE_OT_cyclic_toggle"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = toggle_cyclic_exec; | 
					
						
							|  |  |  | 	ot->invoke = toggle_cyclic_invoke; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* properties */ | 
					
						
							| 
									
										
										
										
											2011-09-19 12:26:20 +00:00
										 |  |  | 	RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction", "Direction to make surface cyclic in"); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | /********************** add duplicate operator *********************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | static int duplicate_exec(bContext *C, wmOperator *op) | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 	ListBase newnurb = {NULL, NULL}; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 	adduplicateflagNurb(obedit, &newnurb, SELECT, false); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-08 06:07:10 +11:00
										 |  |  | 	if (BLI_listbase_is_empty(&newnurb) == false) { | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 		BLI_movelisttolist(object_editcurve_get(obedit), &newnurb); | 
					
						
							|  |  |  | 		WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	else { | 
					
						
							|  |  |  | 		BKE_report(op->reports, RPT_ERROR, "Cannot duplicate current selection"); | 
					
						
							|  |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | void CURVE_OT_duplicate(wmOperatorType *ot) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Duplicate Curve"; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	ot->description = "Duplicate selected control points"; | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->idname = "CURVE_OT_duplicate"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = duplicate_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********************** delete operator *********************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | static int curve_delete_vertices(Object *obedit) | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	if (obedit->type == OB_SURF) { | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 		ed_surf_delete_selected(obedit); | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 	else { | 
					
						
							|  |  |  | 		ed_curve_delete_selected(obedit); | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int curve_delete_segments(Object *obedit, const bool split) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Curve *cu = obedit->data; | 
					
						
							|  |  |  | 	EditNurb *editnurb = cu->editnurb; | 
					
						
							|  |  |  | 	ListBase *nubase = &editnurb->nurbs, newnurb = {NULL, NULL}; | 
					
						
							|  |  |  | 	Nurb *nu, *nu1; | 
					
						
							|  |  |  | 	BezTriple *bezt, *bezt1, *bezt2; | 
					
						
							|  |  |  | 	BPoint *bp, *bp1, *bp2; | 
					
						
							|  |  |  | 	int a, b, starta, enda, cut, cyclicut; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (nu = nubase->first; nu; nu = nu->next) { | 
					
						
							|  |  |  | 		nu1 = NULL; | 
					
						
							|  |  |  | 		starta = enda = cut = -1; | 
					
						
							|  |  |  | 		cyclicut = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (nu->type == CU_BEZIER) { | 
					
						
							|  |  |  | 			for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				if (!BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt)) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					enda = a; | 
					
						
							|  |  |  | 					if (starta == -1) starta = a; | 
					
						
							|  |  |  | 					if (a < nu->pntsu - 1) continue; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				else if (a < nu->pntsu - 1 && !BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt + 1)) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					/* if just single selected point then continue */ | 
					
						
							|  |  |  | 					continue; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (starta >= 0) { | 
					
						
							|  |  |  | 					/* got selected segment, now check where and copy */ | 
					
						
							|  |  |  | 					if (starta <= 1 && a == nu->pntsu - 1) { | 
					
						
							|  |  |  | 						/* copying all points in spline */ | 
					
						
							|  |  |  | 						if (starta == 1 && enda != a) nu->flagu &= ~CU_NURB_CYCLIC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						starta = 0; | 
					
						
							|  |  |  | 						enda = a; | 
					
						
							|  |  |  | 						cut = enda - starta + 1; | 
					
						
							|  |  |  | 						nu1 = BKE_nurb_copy(nu, cut, 1); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else if (starta == 0) { | 
					
						
							|  |  |  | 						/* if start of curve copy next end point */ | 
					
						
							|  |  |  | 						enda++; | 
					
						
							|  |  |  | 						cut = enda - starta + 1; | 
					
						
							|  |  |  | 						bezt1 = &nu->bezt[nu->pntsu - 1]; | 
					
						
							|  |  |  | 						bezt2 = &nu->bezt[nu->pntsu - 2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if ((nu->flagu & CU_NURB_CYCLIC) && | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 						    BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt1) && | 
					
						
							|  |  |  | 						    BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt2)) | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						{ | 
					
						
							|  |  |  | 							/* check if need to join start of spline to end */ | 
					
						
							|  |  |  | 							nu1 = BKE_nurb_copy(nu, cut + 1, 1); | 
					
						
							|  |  |  | 							ED_curve_beztcpy(editnurb, &nu1->bezt[1], nu->bezt, cut); | 
					
						
							|  |  |  | 							starta = nu->pntsu - 1; | 
					
						
							|  |  |  | 							cut = 1; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						else { | 
					
						
							|  |  |  | 							if (nu->flagu & CU_NURB_CYCLIC) cyclicut = cut; | 
					
						
							|  |  |  | 							else nu1 = BKE_nurb_copy(nu, cut, 1); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else if (enda == nu->pntsu - 1) { | 
					
						
							|  |  |  | 						/* if end of curve copy previous start point */ | 
					
						
							|  |  |  | 						starta--; | 
					
						
							|  |  |  | 						cut = enda - starta + 1; | 
					
						
							|  |  |  | 						bezt1 = nu->bezt; | 
					
						
							|  |  |  | 						bezt2 = &nu->bezt[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if ((nu->flagu & CU_NURB_CYCLIC) && | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 						    BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt1) && | 
					
						
							|  |  |  | 						    BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt2)) | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						{ | 
					
						
							|  |  |  | 							/* check if need to join start of spline to end */ | 
					
						
							|  |  |  | 							nu1 = BKE_nurb_copy(nu, cut + 1, 1); | 
					
						
							|  |  |  | 							ED_curve_beztcpy(editnurb, &nu1->bezt[cut], nu->bezt, 1); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						else if (cyclicut != 0) { | 
					
						
							|  |  |  | 							/* if cyclicut exists it is a cyclic spline, start and end should be connected */ | 
					
						
							|  |  |  | 							nu1 = BKE_nurb_copy(nu, cut + cyclicut, 1); | 
					
						
							|  |  |  | 							ED_curve_beztcpy(editnurb, &nu1->bezt[cut], nu->bezt, cyclicut); | 
					
						
							|  |  |  | 							cyclicut = 0; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						else { | 
					
						
							|  |  |  | 							nu1 = BKE_nurb_copy(nu, cut, 1); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						/* mid spline selection, copy adjacent start and end */ | 
					
						
							|  |  |  | 						starta--; | 
					
						
							|  |  |  | 						enda++; | 
					
						
							|  |  |  | 						cut = enda - starta + 1; | 
					
						
							|  |  |  | 						nu1 = BKE_nurb_copy(nu, cut, 1); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					if (nu1 != NULL) { | 
					
						
							|  |  |  | 						ED_curve_beztcpy(editnurb, nu1->bezt, &nu->bezt[starta], cut); | 
					
						
							|  |  |  | 						BLI_addtail(&newnurb, nu1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if (starta != 0 || enda != nu->pntsu - 1) nu1->flagu &= ~CU_NURB_CYCLIC; | 
					
						
							|  |  |  | 						nu1 = NULL; | 
					
						
							| 
									
										
										
										
											2012-03-03 16:31:46 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					starta = enda = -1; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!split && cut != -1 && nu->pntsu > 2 && !(nu->flagu & CU_NURB_CYCLIC)) { | 
					
						
							|  |  |  | 				/* start and points copied if connecting segment was deleted and not cylic spline */ | 
					
						
							|  |  |  | 				bezt1 = nu->bezt; | 
					
						
							|  |  |  | 				bezt2 = &nu->bezt[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt1) && | 
					
						
							|  |  |  | 				    BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt2)) | 
					
						
							| 
									
										
										
										
											2013-10-23 02:52:27 +00:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					nu1 = BKE_nurb_copy(nu, 1, 1); | 
					
						
							|  |  |  | 					ED_curve_beztcpy(editnurb, nu1->bezt, bezt1, 1); | 
					
						
							|  |  |  | 					BLI_addtail(&newnurb, nu1); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				bezt1 = &nu->bezt[nu->pntsu - 1]; | 
					
						
							|  |  |  | 				bezt2 = &nu->bezt[nu->pntsu - 2]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt1) && | 
					
						
							|  |  |  | 				    BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt2)) | 
					
						
							| 
									
										
										
										
											2013-10-23 02:52:27 +00:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					nu1 = BKE_nurb_copy(nu, 1, 1); | 
					
						
							|  |  |  | 					ED_curve_beztcpy(editnurb, nu1->bezt, bezt1, 1); | 
					
						
							|  |  |  | 					BLI_addtail(&newnurb, nu1); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 		else if (nu->pntsv >= 1) { | 
					
						
							|  |  |  | 			int u, v; | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 			if (isNurbselV(nu, &u, SELECT)) { | 
					
						
							|  |  |  | 				for (a = 0, bp = nu->bp; a < nu->pntsu; a++, bp++) { | 
					
						
							|  |  |  | 					if (!(bp->f1 & SELECT)) { | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 						enda = a; | 
					
						
							|  |  |  | 						if (starta == -1) starta = a; | 
					
						
							|  |  |  | 						if (a < nu->pntsu - 1) continue; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					else if (a < nu->pntsu - 1 && !((bp + 1)->f1 & SELECT)) { | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 						/* if just single selected point then continue */ | 
					
						
							|  |  |  | 						continue; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (starta >= 0) { | 
					
						
							|  |  |  | 						/* got selected segment, now check where and copy */ | 
					
						
							|  |  |  | 						if (starta <= 1 && a == nu->pntsu - 1) { | 
					
						
							|  |  |  | 							/* copying all points in spline */ | 
					
						
							|  |  |  | 							if (starta == 1 && enda != a) nu->flagu &= ~CU_NURB_CYCLIC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							starta = 0; | 
					
						
							|  |  |  | 							enda = a; | 
					
						
							|  |  |  | 							cut = enda - starta + 1; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							nu1 = BKE_nurb_copy(nu, cut, nu->pntsv); | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 						else if (starta == 0) { | 
					
						
							|  |  |  | 							/* if start of curve copy next end point */ | 
					
						
							|  |  |  | 							enda++; | 
					
						
							|  |  |  | 							cut = enda - starta + 1; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							bp1 = &nu->bp[nu->pntsu - 1]; | 
					
						
							|  |  |  | 							bp2 = &nu->bp[nu->pntsu - 2]; | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							if ((nu->flagu & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 								/* check if need to join start of spline to end */ | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 								nu1 = BKE_nurb_copy(nu, cut + 1, nu->pntsv); | 
					
						
							|  |  |  | 								for (b = 0; b < nu->pntsv; b++) { | 
					
						
							|  |  |  | 									ED_curve_bpcpy(editnurb, &nu1->bp[b * nu1->pntsu + 1], &nu->bp[b * nu->pntsu], cut); | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 								starta = nu->pntsu - 1; | 
					
						
							|  |  |  | 								cut = 1; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							else { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 								if (nu->flagu & CU_NURB_CYCLIC) cyclicut = cut; | 
					
						
							|  |  |  | 								else nu1 = BKE_nurb_copy(nu, cut, nu->pntsv); | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						else if (enda == nu->pntsu - 1) { | 
					
						
							|  |  |  | 							/* if end of curve copy previous start point */ | 
					
						
							|  |  |  | 							starta--; | 
					
						
							|  |  |  | 							cut = enda - starta + 1; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							bp1 = nu->bp; | 
					
						
							|  |  |  | 							bp2 = &nu->bp[1]; | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							if ((nu->flagu & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 								/* check if need to join start of spline to end */ | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 								nu1 = BKE_nurb_copy(nu, cut + 1, nu->pntsv); | 
					
						
							|  |  |  | 								for (b = 0; b < nu->pntsv; b++) { | 
					
						
							|  |  |  | 									ED_curve_bpcpy(editnurb, &nu1->bp[b * nu1->pntsu + cut], &nu->bp[b * nu->pntsu], 1); | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							else if (cyclicut != 0) { | 
					
						
							|  |  |  | 								/* if cyclicut exists it is a cyclic spline, start and end should be connected */ | 
					
						
							|  |  |  | 								nu1 = BKE_nurb_copy(nu, cut + cyclicut, nu->pntsv); | 
					
						
							|  |  |  | 								for (b = 0; b < nu->pntsv; b++) { | 
					
						
							|  |  |  | 									ED_curve_bpcpy(editnurb, &nu1->bp[b * nu1->pntsu + cut], &nu->bp[b * nu->pntsu], cyclicut); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 							else { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 								nu1 = BKE_nurb_copy(nu, cut, nu->pntsv); | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						else { | 
					
						
							|  |  |  | 							/* mid spline selection, copy adjacent start and end */ | 
					
						
							|  |  |  | 							starta--; | 
					
						
							|  |  |  | 							enda++; | 
					
						
							|  |  |  | 							cut = enda - starta + 1; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							nu1 = BKE_nurb_copy(nu, cut, nu->pntsv); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 						if (nu1 != NULL) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							for (b = 0; b < nu->pntsv; b++) { | 
					
						
							|  |  |  | 								ED_curve_bpcpy(editnurb, &nu1->bp[b * nu1->pntsu], &nu->bp[b * nu->pntsu + starta], cut); | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 							} | 
					
						
							|  |  |  | 							BLI_addtail(&newnurb, nu1); | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 							if (starta != 0 || enda != nu->pntsu - 1) nu1->flagu &= ~CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 							nu1 = NULL; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						starta = enda = -1; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (!split && cut != -1 && nu->pntsu > 2 && !(nu->flagu & CU_NURB_CYCLIC)) { | 
					
						
							|  |  |  | 					/* start and points copied if connecting segment was deleted and not cylic spline */ | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					bp1 = nu->bp; | 
					
						
							|  |  |  | 					bp2 = &nu->bp[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { | 
					
						
							|  |  |  | 						nu1 = BKE_nurb_copy(nu, 1, nu->pntsv); | 
					
						
							|  |  |  | 						for (b = 0; b < nu->pntsv; b++) { | 
					
						
							|  |  |  | 							ED_curve_bpcpy(editnurb, &nu1->bp[b], &nu->bp[b * nu->pntsu], 1); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 						BLI_addtail(&newnurb, nu1); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					bp1 = &nu->bp[nu->pntsu - 1]; | 
					
						
							|  |  |  | 					bp2 = &nu->bp[nu->pntsu - 2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { | 
					
						
							|  |  |  | 						nu1 = BKE_nurb_copy(nu, 1, nu->pntsv); | 
					
						
							|  |  |  | 						for (b = 0; b < nu->pntsv; b++) { | 
					
						
							|  |  |  | 							ED_curve_bpcpy(editnurb, &nu1->bp[b], &nu->bp[b * nu->pntsu + nu->pntsu - 1], 1); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 						BLI_addtail(&newnurb, nu1); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 			else if (isNurbselU(nu, &v, SELECT)) { | 
					
						
							|  |  |  | 				for (a = 0, bp = nu->bp; a < nu->pntsv; a++, bp += nu->pntsu) { | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 					if (!(bp->f1 & SELECT)) { | 
					
						
							|  |  |  | 						enda = a; | 
					
						
							|  |  |  | 						if (starta == -1) starta = a; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						if (a < nu->pntsv - 1) continue; | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					else if (a < nu->pntsv - 1 && !((bp + nu->pntsu)->f1 & SELECT)) { | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 						/* if just single selected point then continue */ | 
					
						
							|  |  |  | 						continue; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (starta >= 0) { | 
					
						
							|  |  |  | 						/* got selected segment, now check where and copy */ | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						if (starta <= 1 && a == nu->pntsv - 1) { | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 							/* copying all points in spline */ | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							if (starta == 1 && enda != a) nu->flagv &= ~CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 							starta = 0; | 
					
						
							|  |  |  | 							enda = a; | 
					
						
							|  |  |  | 							cut = enda - starta + 1; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							nu1 = BKE_nurb_copy(nu, nu->pntsu, cut); | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						else if (starta == 0) { | 
					
						
							|  |  |  | 							/* if start of curve copy next end point */ | 
					
						
							|  |  |  | 							enda++; | 
					
						
							|  |  |  | 							cut = enda - starta + 1; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							bp1 = &nu->bp[nu->pntsv * nu->pntsu - nu->pntsu]; | 
					
						
							|  |  |  | 							bp2 = &nu->bp[nu->pntsv * nu->pntsu - (nu->pntsu * 2)]; | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							if ((nu->flagv & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 								/* check if need to join start of spline to end */ | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 								nu1 = BKE_nurb_copy(nu, nu->pntsu, cut + 1); | 
					
						
							|  |  |  | 								ED_curve_bpcpy(editnurb, &nu1->bp[nu->pntsu], nu->bp, cut * nu->pntsu); | 
					
						
							|  |  |  | 								starta = nu->pntsv - 1; | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 								cut = 1; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							else { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 								if (nu->flagv & CU_NURB_CYCLIC) cyclicut = cut; | 
					
						
							|  |  |  | 								else nu1 = BKE_nurb_copy(nu, nu->pntsu, cut); | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						else if (enda == nu->pntsv - 1) { | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 							/* if end of curve copy previous start point */ | 
					
						
							|  |  |  | 							starta--; | 
					
						
							|  |  |  | 							cut = enda - starta + 1; | 
					
						
							|  |  |  | 							bp1 = nu->bp; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							bp2 = &nu->bp[nu->pntsu]; | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							if ((nu->flagv & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 								/* check if need to join start of spline to end */ | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 								nu1 = BKE_nurb_copy(nu, nu->pntsu, cut + 1); | 
					
						
							|  |  |  | 								ED_curve_bpcpy(editnurb, &nu1->bp[cut * nu->pntsu], nu->bp, nu->pntsu); | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							else if (cyclicut != 0) { | 
					
						
							|  |  |  | 								/* if cyclicut exists it is a cyclic spline, start and end should be connected */ | 
					
						
							|  |  |  | 								nu1 = BKE_nurb_copy(nu, nu->pntsu, cut + cyclicut); | 
					
						
							|  |  |  | 								ED_curve_bpcpy(editnurb, &nu1->bp[cut * nu->pntsu], nu->bp, nu->pntsu * cyclicut); | 
					
						
							|  |  |  | 								cyclicut = 0; | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 							} | 
					
						
							|  |  |  | 							else { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 								nu1 = BKE_nurb_copy(nu, nu->pntsu, cut); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						else { | 
					
						
							|  |  |  | 							/* mid spline selection, copy adjacent start and end */ | 
					
						
							|  |  |  | 							starta--; | 
					
						
							|  |  |  | 							enda++; | 
					
						
							|  |  |  | 							cut = enda - starta + 1; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							nu1 = BKE_nurb_copy(nu, nu->pntsu, cut); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2011-02-13 19:04:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 						if (nu1 != NULL) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 							ED_curve_bpcpy(editnurb, nu1->bp, &nu->bp[starta * nu->pntsu], cut * nu->pntsu); | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 							BLI_addtail(&newnurb, nu1); | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 							if (starta != 0 || enda != nu->pntsv - 1) nu1->flagv &= ~CU_NURB_CYCLIC; | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 							nu1 = NULL; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						starta = enda = -1; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 				if (!split && cut != -1 && nu->pntsv > 2 && !(nu->flagv & CU_NURB_CYCLIC)) { | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 					/* start and points copied if connecting segment was deleted and not cylic spline */ | 
					
						
							|  |  |  | 					bp1 = nu->bp; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					bp2 = &nu->bp[nu->pntsu]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 					if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						nu1 = BKE_nurb_copy(nu, nu->pntsu, 1); | 
					
						
							|  |  |  | 						ED_curve_bpcpy(editnurb, nu1->bp, nu->bp, nu->pntsu); | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 						BLI_addtail(&newnurb, nu1); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2011-09-22 12:07:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 					bp1 = &nu->bp[nu->pntsu * nu->pntsv - nu->pntsu]; | 
					
						
							|  |  |  | 					bp2 = &nu->bp[nu->pntsu * nu->pntsv - (nu->pntsu * 2)]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 					if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 						nu1 = BKE_nurb_copy(nu, nu->pntsu, 1); | 
					
						
							|  |  |  | 						ED_curve_bpcpy(editnurb, nu1->bp, &nu->bp[nu->pntsu * nu->pntsv - nu->pntsu], nu->pntsu); | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 						BLI_addtail(&newnurb, nu1); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 			else { | 
					
						
							|  |  |  | 				/* selection not valid, just copy nurb to new list */ | 
					
						
							|  |  |  | 				nu1 = BKE_nurb_copy(nu, nu->pntsu, nu->pntsv); | 
					
						
							|  |  |  | 				ED_curve_bpcpy(editnurb, nu1->bp, nu->bp, nu->pntsu * nu->pntsv); | 
					
						
							|  |  |  | 				BLI_addtail(&newnurb, nu1); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (nu = newnurb.first; nu; nu = nu->next) { | 
					
						
							|  |  |  | 		if (nu->type == CU_BEZIER) { | 
					
						
							|  |  |  | 			if (split) { | 
					
						
							|  |  |  | 				/* deselect for split operator */ | 
					
						
							|  |  |  | 				for (b = 0, bezt1 = nu->bezt; b < nu->pntsu; b++, bezt1++) { | 
					
						
							|  |  |  | 					select_beztriple(bezt1, DESELECT, SELECT, true); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			BKE_nurb_handles_calc(nu); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			if (split) { | 
					
						
							|  |  |  | 				/* deselect for split operator */ | 
					
						
							|  |  |  | 				for (b = 0, bp1 = nu->bp; b < nu->pntsu * nu->pntsv; b++, bp1++) { | 
					
						
							|  |  |  | 					select_bpoint(bp1, DESELECT, SELECT, HIDDEN); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			BKE_nurb_order_clamp_u(nu); | 
					
						
							|  |  |  | 			BKE_nurb_knot_calc_u(nu); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (nu->pntsv > 1) { | 
					
						
							|  |  |  | 				BKE_nurb_order_clamp_v(nu); | 
					
						
							|  |  |  | 				BKE_nurb_knot_calc_v(nu); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	keyIndex_delNurbList(editnurb, nubase); | 
					
						
							|  |  |  | 	BKE_nurbList_free(nubase); | 
					
						
							|  |  |  | 	BLI_movelisttolist(nubase, &newnurb); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-29 03:14:36 +00:00
										 |  |  | static int curve_delete_exec(bContext *C, wmOperator *op) | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							| 
									
										
										
										
											2013-11-05 23:37:09 +00:00
										 |  |  | 	Curve *cu = (Curve *)obedit->data; | 
					
						
							| 
									
										
										
										
											2013-08-29 03:00:04 +00:00
										 |  |  | 	eCurveElem_Types type = RNA_enum_get(op->ptr, "type"); | 
					
						
							| 
									
										
										
										
											2013-11-25 05:36:38 +01:00
										 |  |  | 	int retval = OPERATOR_CANCELLED; | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (type == CURVE_VERTEX) retval = curve_delete_vertices(obedit); | 
					
						
							|  |  |  | 	else if (type == CURVE_SEGMENT) retval = curve_delete_segments(obedit, false); | 
					
						
							|  |  |  | 	else BLI_assert(0); | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (retval == OPERATOR_FINISHED) { | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 		cu->actnu = cu->actvert = CU_ACT_NONE; | 
					
						
							| 
									
										
										
										
											2013-11-05 23:37:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-29 02:32:51 +00:00
										 |  |  | 		if (ED_curve_updateAnimPaths(obedit->data)) WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							|  |  |  | 		DAG_id_tag_update(obedit->data, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return retval; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return retval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-29 03:14:36 +00:00
										 |  |  | static EnumPropertyItem curve_delete_type_items[] = { | 
					
						
							| 
									
										
										
										
											2013-09-15 01:46:25 +00:00
										 |  |  | 	{CURVE_VERTEX, "VERT", 0, "Vertices", ""}, | 
					
						
							| 
									
										
										
										
											2013-08-29 03:14:36 +00:00
										 |  |  | 	{CURVE_SEGMENT, "SEGMENT", 0, "Segments", ""}, | 
					
						
							|  |  |  | 	{0, NULL, 0, NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static EnumPropertyItem *rna_curve_delete_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), | 
					
						
							| 
									
										
										
										
											2014-01-04 18:08:43 +11:00
										 |  |  |                                                             PropertyRNA *UNUSED(prop), bool *r_free) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:14:36 +00:00
										 |  |  | 	EnumPropertyItem *item = NULL; | 
					
						
							|  |  |  | 	int totitem = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!C) /* needed for docs and i18n tools */ | 
					
						
							|  |  |  | 		return curve_delete_type_items; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 19:57:14 +00:00
										 |  |  | 	RNA_enum_items_add_value(&item, &totitem, curve_delete_type_items, CURVE_VERTEX); | 
					
						
							|  |  |  | 	RNA_enum_items_add_value(&item, &totitem, curve_delete_type_items, CURVE_SEGMENT); | 
					
						
							| 
									
										
										
										
											2013-08-29 03:14:36 +00:00
										 |  |  | 	RNA_enum_item_end(&item, &totitem); | 
					
						
							| 
									
										
										
										
											2014-01-04 18:08:43 +11:00
										 |  |  | 	*r_free = true; | 
					
						
							| 
									
										
										
										
											2013-08-29 03:14:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return item; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CURVE_OT_delete(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-08-29 03:14:36 +00:00
										 |  |  | 	PropertyRNA *prop; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Delete"; | 
					
						
							| 
									
										
										
										
											2011-04-04 20:31:01 +00:00
										 |  |  | 	ot->description = "Delete selected control points or segments"; | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->idname = "CURVE_OT_delete"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2013-08-29 03:14:36 +00:00
										 |  |  | 	ot->exec = curve_delete_exec; | 
					
						
							|  |  |  | 	ot->invoke = WM_menu_invoke; | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* properties */ | 
					
						
							| 
									
										
										
										
											2013-08-29 03:14:36 +00:00
										 |  |  | 	prop = RNA_def_enum(ot->srna, "type", curve_delete_type_items, 0, "Type", "Which elements to delete"); | 
					
						
							|  |  |  | 	RNA_def_enum_funcs(prop, rna_curve_delete_type_itemf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ot->prop = prop; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-21 00:36:07 +00:00
										 |  |  | /********************** shade smooth/flat operator *********************/ | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-21 00:36:07 +00:00
										 |  |  | static int shade_smooth_exec(bContext *C, wmOperator *op) | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu; | 
					
						
							| 
									
										
										
										
											2015-01-26 16:03:11 +01:00
										 |  |  | 	int clear = (STREQ(op->idname, "CURVE_OT_shade_flat")); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (obedit->type != OB_CURVE) | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 		if (ED_curve_nurb_select_check(obedit->data, nu)) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (!clear) nu->flag |= CU_SMOOTH; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 			else nu->flag &= ~CU_SMOOTH; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-21 00:36:07 +00:00
										 |  |  | void CURVE_OT_shade_smooth(wmOperatorType *ot) | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Shade Smooth"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_shade_smooth"; | 
					
						
							| 
									
										
										
										
											2012-05-04 15:00:36 +00:00
										 |  |  | 	ot->description = "Set shading to smooth"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = shade_smooth_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-07-21 00:36:07 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-21 00:36:07 +00:00
										 |  |  | void CURVE_OT_shade_flat(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Shade Flat"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_shade_flat"; | 
					
						
							| 
									
										
										
										
											2012-05-04 15:00:36 +00:00
										 |  |  | 	ot->description = "Set shading to flat"; | 
					
						
							| 
									
										
										
										
											2009-07-21 00:36:07 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = shade_smooth_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editsurfcurve; | 
					
						
							| 
									
										
										
										
											2009-07-21 00:36:07 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | /************** join operator, to be used externally? ****************/ | 
					
						
							| 
									
										
										
										
											2012-09-19 12:11:28 +00:00
										 |  |  | /* TODO: shape keys - as with meshes */ | 
					
						
							| 
									
										
										
										
											2013-07-10 09:55:10 +00:00
										 |  |  | int join_curve_exec(bContext *C, wmOperator *op) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Main *bmain = CTX_data_main(C); | 
					
						
							|  |  |  | 	Scene *scene = CTX_data_scene(C); | 
					
						
							|  |  |  | 	Object *ob = CTX_data_active_object(C); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Curve *cu; | 
					
						
							|  |  |  | 	Nurb *nu, *newnu; | 
					
						
							|  |  |  | 	BezTriple *bezt; | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							|  |  |  | 	ListBase tempbase; | 
					
						
							|  |  |  | 	float imat[4][4], cmat[4][4]; | 
					
						
							|  |  |  | 	int a; | 
					
						
							| 
									
										
										
										
											2013-07-10 09:55:10 +00:00
										 |  |  | 	bool ok = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (base->object == ob) { | 
					
						
							|  |  |  | 			ok = true; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	CTX_DATA_END; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* that way the active object is always selected */ | 
					
						
							|  |  |  | 	if (ok == false) { | 
					
						
							|  |  |  | 		BKE_report(op->reports, RPT_WARNING, "Active object is not a selected curve"); | 
					
						
							|  |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-08 06:07:10 +11:00
										 |  |  | 	BLI_listbase_clear(&tempbase); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* trasnform all selected curves inverse in obact */ | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | 	invert_m4_m4(imat, ob->obmat); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-06-05 21:54:21 +00:00
										 |  |  | 	CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases) | 
					
						
							| 
									
										
										
										
											2012-04-30 16:22:40 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		if (base->object->type == ob->type) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (base->object != ob) { | 
					
						
							| 
									
										
										
										
											2009-07-13 00:40:20 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				cu = base->object->data; | 
					
						
							| 
									
										
										
										
											2009-07-13 00:40:20 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (cu->nurb.first) { | 
					
						
							| 
									
										
										
										
											2009-07-13 00:40:20 +00:00
										 |  |  | 					/* watch it: switch order here really goes wrong */ | 
					
						
							| 
									
										
										
										
											2013-05-26 18:36:25 +00:00
										 |  |  | 					mul_m4_m4m4(cmat, imat, base->object->obmat); | 
					
						
							| 
									
										
										
										
											2009-07-13 00:40:20 +00:00
										 |  |  | 					 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 					nu = cu->nurb.first; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 					while (nu) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						newnu = BKE_nurb_duplicate(nu); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 						if (ob->totcol) { /* TODO, merge material lists */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							CLAMP(newnu->mat_nr, 0, ob->totcol - 1); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 						else { | 
					
						
							|  |  |  | 							newnu->mat_nr = 0; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2009-07-13 00:40:20 +00:00
										 |  |  | 						BLI_addtail(&tempbase, newnu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 						 | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 						if ((bezt = newnu->bezt)) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							a = newnu->pntsu; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 							while (a--) { | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | 								mul_m4_v3(cmat, bezt->vec[0]); | 
					
						
							|  |  |  | 								mul_m4_v3(cmat, bezt->vec[1]); | 
					
						
							|  |  |  | 								mul_m4_v3(cmat, bezt->vec[2]); | 
					
						
							| 
									
										
										
										
											2009-07-13 00:40:20 +00:00
										 |  |  | 								bezt++; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 							BKE_nurb_handles_calc(newnu); | 
					
						
							| 
									
										
										
										
											2009-07-13 00:40:20 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 						if ((bp = newnu->bp)) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 							a = newnu->pntsu * nu->pntsv; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 							while (a--) { | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | 								mul_m4_v3(cmat, bp->vec); | 
					
						
							| 
									
										
										
										
											2009-07-13 00:40:20 +00:00
										 |  |  | 								bp++; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 						nu = nu->next; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-07-13 00:40:20 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2010-08-01 12:47:49 +00:00
										 |  |  | 				ED_base_object_free_and_unlink(bmain, scene, base); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-07-13 00:40:20 +00:00
										 |  |  | 	CTX_DATA_END; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	cu = ob->data; | 
					
						
							| 
									
										
										
										
											2010-12-21 14:49:34 +00:00
										 |  |  | 	BLI_movelisttolist(&cu->nurb, &tempbase); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-02-21 19:33:04 +00:00
										 |  |  | 	DAG_relations_tag_update(bmain);   // because we removed object(s), call before editmode!
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-03-21 14:18:17 +00:00
										 |  |  | 	ED_object_editmode_enter(C, EM_WAITCURSOR); | 
					
						
							|  |  |  | 	ED_object_editmode_exit(C, EM_FREEDATA | EM_WAITCURSOR | EM_DO_UNDO); | 
					
						
							| 
									
										
										
										
											2009-07-13 00:40:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); | 
					
						
							| 
									
										
										
											
												2.5: Most curve/surface editmode operators back:
* Hide, Reveal
* Separate, Duplicate, Delete
* Set Weight, Set Radius, Set Spline Type, Set Handle Type, Set Smooth
* Tilt, Clear Tilt
* Smooth, Smooth Radius
* De(select) First, De(select) Last, De(select) All, Select Inverse,
  Select Linked, Select Control Point Row, Select Next, Select Previous,
  Select More, Select Less, Select Random, Select Every Nth
* Switch Direction, Subdivide, Make Segment, Spin, Extrude, Toggle Cyclic
* Specials Menu
Not working correct yet:
* Add Vertex (ctrl click)
* Add Menu
											
										 
											2009-02-12 22:12:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | /***************** clear tilt operator ********************/ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-15 01:36:14 +00:00
										 |  |  | static int clear_tilt_exec(bContext *C, wmOperator *UNUSED(op)) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	Curve *cu = obedit->data; | 
					
						
							|  |  |  | 	ListBase *editnurb = object_editcurve_get(obedit); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu; | 
					
						
							|  |  |  | 	BezTriple *bezt; | 
					
						
							|  |  |  | 	BPoint *bp; | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = editnurb->first; nu; nu = nu->next) { | 
					
						
							|  |  |  | 		if (nu->bezt) { | 
					
						
							|  |  |  | 			bezt = nu->bezt; | 
					
						
							|  |  |  | 			a = nu->pntsu; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							| 
									
										
										
										
											2015-07-09 14:31:27 +10:00
										 |  |  | 				if (BEZT_ISSEL_ANY_HIDDENHANDLES(cu, bezt)) bezt->alfa = 0.0; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				bezt++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		else if (nu->bp) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 			bp = nu->bp; | 
					
						
							|  |  |  | 			a = nu->pntsu * nu->pntsv; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 				if (bp->f1 & SELECT) bp->alfa = 0.0f; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 				bp++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 	DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-29 02:15:13 +00:00
										 |  |  | void CURVE_OT_tilt_clear(wmOperatorType *ot) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Clear Tilt"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_tilt_clear"; | 
					
						
							| 
									
										
										
										
											2012-05-04 15:00:36 +00:00
										 |  |  | 	ot->description = "Clear the tilt of selected control points"; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = clear_tilt_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editcurve; | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-11 23:02:21 +00:00
										 |  |  | /****************** undo for curves ****************/ | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 10:56:20 +06:00
										 |  |  | static void undoCurve_to_editCurve(void *ucu, void *UNUSED(edata), void *cu_v) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Curve *cu = cu_v; | 
					
						
							|  |  |  | 	UndoCurve *undoCurve = ucu; | 
					
						
							|  |  |  | 	ListBase *undobase = &undoCurve->nubase; | 
					
						
							|  |  |  | 	ListBase *editbase = BKE_curve_editNurbs_get(cu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu, *newnu; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	EditNurb *editnurb = cu->editnurb; | 
					
						
							|  |  |  | 	AnimData *ad = BKE_animdata_from_id(&cu->id); | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 	BKE_nurbList_free(editbase); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	if (undoCurve->undoIndex) { | 
					
						
							| 
									
										
										
										
											2013-05-21 08:45:10 +00:00
										 |  |  | 		BLI_ghash_free(editnurb->keyindex, NULL, MEM_freeN); | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		editnurb->keyindex = dupli_keyIndexHash(undoCurve->undoIndex); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (ad) { | 
					
						
							|  |  |  | 		if (ad->action) { | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | 			free_fcurves(&ad->action->curves); | 
					
						
							|  |  |  | 			copy_fcurves(&ad->action->curves, &undoCurve->fcurves); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		free_fcurves(&ad->drivers); | 
					
						
							|  |  |  | 		copy_fcurves(&ad->drivers, &undoCurve->drivers); | 
					
						
							| 
									
										
										
										
											2010-12-20 19:47:16 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	/* copy  */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = undobase->first; nu; nu = nu->next) { | 
					
						
							|  |  |  | 		newnu = BKE_nurb_duplicate(nu); | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 		if (editnurb->keyindex) { | 
					
						
							|  |  |  | 			keyIndex_updateNurb(editnurb, nu, newnu); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | 		BLI_addtail(editbase, newnu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 	cu->actvert = undoCurve->actvert; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	cu->actnu = undoCurve->actnu; | 
					
						
							| 
									
										
										
										
											2014-11-20 18:58:24 +01:00
										 |  |  | 	cu->flag = undoCurve->flag; | 
					
						
							| 
									
										
										
										
											2012-04-16 08:04:12 +00:00
										 |  |  | 	ED_curve_updateAnimPaths(cu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 10:56:20 +06:00
										 |  |  | static void *editCurve_to_undoCurve(void *UNUSED(edata), void *cu_v) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Curve *cu = cu_v; | 
					
						
							|  |  |  | 	ListBase *nubase = BKE_curve_editNurbs_get(cu); | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | 	UndoCurve *undoCurve; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	EditNurb *editnurb = cu->editnurb, tmpEditnurb; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	Nurb *nu, *newnu; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	AnimData *ad = BKE_animdata_from_id(&cu->id); | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	undoCurve = MEM_callocN(sizeof(UndoCurve), "undoCurve"); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	if (editnurb->keyindex) { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 		undoCurve->undoIndex = dupli_keyIndexHash(editnurb->keyindex); | 
					
						
							|  |  |  | 		tmpEditnurb.keyindex = undoCurve->undoIndex; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (ad) { | 
					
						
							|  |  |  | 		if (ad->action) | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | 			copy_fcurves(&undoCurve->fcurves, &ad->action->curves); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		copy_fcurves(&undoCurve->drivers, &ad->drivers); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-12-20 19:47:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	/* copy  */ | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	for (nu = nubase->first; nu; nu = nu->next) { | 
					
						
							|  |  |  | 		newnu = BKE_nurb_duplicate(nu); | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 		if (undoCurve->undoIndex) { | 
					
						
							|  |  |  | 			keyIndex_updateNurb(&tmpEditnurb, nu, newnu); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | 		BLI_addtail(&undoCurve->nubase, newnu); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 	undoCurve->actvert = cu->actvert; | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	undoCurve->actnu = cu->actnu; | 
					
						
							| 
									
										
										
										
											2014-11-20 18:58:24 +01:00
										 |  |  | 	undoCurve->flag = cu->flag; | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return undoCurve; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | static void free_undoCurve(void *ucv) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	UndoCurve *undoCurve = ucv; | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-28 16:49:00 +00:00
										 |  |  | 	BKE_nurbList_free(&undoCurve->nubase); | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (undoCurve->undoIndex) | 
					
						
							| 
									
										
										
										
											2013-05-21 08:45:10 +00:00
										 |  |  | 		BLI_ghash_free(undoCurve->undoIndex, NULL, MEM_freeN); | 
					
						
							| 
									
										
										
										
											2010-12-20 19:47:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	free_fcurves(&undoCurve->fcurves); | 
					
						
							| 
									
										
										
										
											2011-02-04 21:10:27 +00:00
										 |  |  | 	free_fcurves(&undoCurve->drivers); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-30 04:48:40 +00:00
										 |  |  | 	MEM_freeN(undoCurve); | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void *get_data(bContext *C) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:49:57 +00:00
										 |  |  | 	return obedit; | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* and this is all the undo system needs to know */ | 
					
						
							| 
									
										
										
										
											2010-11-17 09:45:45 +00:00
										 |  |  | void undo_push_curve(bContext *C, const char *name) | 
					
						
							| 
									
										
										
										
											2009-01-14 12:26:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	undo_editmode_push(C, name, get_data, free_undoCurve, undoCurve_to_editCurve, editCurve_to_undoCurve, NULL); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void ED_curve_beztcpy(EditNurb *editnurb, BezTriple *dst, BezTriple *src, int count) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	memcpy(dst, src, count * sizeof(BezTriple)); | 
					
						
							| 
									
										
										
										
											2010-12-06 21:18:08 +00:00
										 |  |  | 	keyIndex_updateBezt(editnurb, src, dst, count); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ED_curve_bpcpy(EditNurb *editnurb, BPoint *dst, BPoint *src, int count) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 11:42:29 +00:00
										 |  |  | 	memcpy(dst, src, count * sizeof(BPoint)); | 
					
						
							| 
									
										
										
										
											2010-12-06 21:18:08 +00:00
										 |  |  | 	keyIndex_updateBP(editnurb, src, dst, count); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:57:36 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-11-15 06:37:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | bool ED_curve_active_center(Curve *cu, float center[3]) | 
					
						
							| 
									
										
										
										
											2011-11-15 06:37:47 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 	Nurb *nu = NULL; | 
					
						
							|  |  |  | 	void *vert = NULL; | 
					
						
							| 
									
										
										
										
											2011-11-15 06:37:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 	if (!BKE_curve_nurb_vert_active_get(cu, &nu, &vert)) | 
					
						
							|  |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2011-11-15 06:37:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 	if (nu->type == CU_BEZIER) { | 
					
						
							|  |  |  | 		BezTriple *bezt = (BezTriple *)vert; | 
					
						
							| 
									
										
										
										
											2011-11-15 06:37:47 +00:00
										 |  |  | 		copy_v3_v3(center, bezt->vec[1]); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 		BPoint *bp = (BPoint *)vert; | 
					
						
							| 
									
										
										
										
											2011-11-15 06:37:47 +00:00
										 |  |  | 		copy_v3_v3(center, bp->vec); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-27 15:18:40 +11:00
										 |  |  | 	return true; | 
					
						
							| 
									
										
										
										
											2011-11-15 06:37:47 +00:00
										 |  |  | } | 
					
						
							| 
									
										
											  
											
												Move curve's boundbox and texspace calculation out of modifier stack
There were several issues with how bounding box and texture space
are calculated:
- This was done at the same time as applying modifiers, meaning if
  several objects are sharing the same curve datablock, bounding
  box and texture space will be calculated multiple times.
  Further, allocating bounding box wasn't safe for threading.
- Bounding box and texture space were evaluated after pre-tessellation
  modifiers are applied. This means Curve-level data is actually
  depends on object data, and it's really bad because different
  objects could have different modifiers and this leads to
  conflicts (curve's data depends on object evaluation order)
  and doesn't behave in a predictable way.
  This commit moves bounding box and texture space evaluation from
  modifier stack to own utility functions, just like it's was done
  for meshes.
  This makes curve objects update thread-safe, but gives some
  limitations as well. Namely, with such approach it's not so
  clear how to preserve the same behavior of texture space:
  before this change texture space and bounding box would match
  beveled curve as accurate as possible.
  Old behavior was nice for quick texturing -- in most cases you
  didn't need to modify texture space at all. But texture space
  was depending on render/preview settings which could easily lead
  to situations, when final result would be far different from
  preview one.
  Now we're using CV points coordinates and their radius to approximate
  the bounding box. This doesn't give the same exact texture space,
  but it helps a lot keeping texture space in a nice predictable way.
  We could make approximation smarter in the future, but fir now
  added operator to match texture space to fully tessellated curve
  called "Match Texture Space".
Review link:
  https://codereview.appspot.com/15410043/
Brief description:
  http://wiki.blender.org/index.php/User:Nazg-gul/GSoC-2013/Results#Curve_Texture_Space
											
										 
											2013-10-20 14:41:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /******************** Match texture space operator ***********************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int match_texture_space_poll(bContext *C) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *object = CTX_data_active_object(C); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-20 01:30:29 +10:00
										 |  |  | 	return object && ELEM(object->type, OB_CURVE, OB_SURF, OB_FONT); | 
					
						
							| 
									
										
											  
											
												Move curve's boundbox and texspace calculation out of modifier stack
There were several issues with how bounding box and texture space
are calculated:
- This was done at the same time as applying modifiers, meaning if
  several objects are sharing the same curve datablock, bounding
  box and texture space will be calculated multiple times.
  Further, allocating bounding box wasn't safe for threading.
- Bounding box and texture space were evaluated after pre-tessellation
  modifiers are applied. This means Curve-level data is actually
  depends on object data, and it's really bad because different
  objects could have different modifiers and this leads to
  conflicts (curve's data depends on object evaluation order)
  and doesn't behave in a predictable way.
  This commit moves bounding box and texture space evaluation from
  modifier stack to own utility functions, just like it's was done
  for meshes.
  This makes curve objects update thread-safe, but gives some
  limitations as well. Namely, with such approach it's not so
  clear how to preserve the same behavior of texture space:
  before this change texture space and bounding box would match
  beveled curve as accurate as possible.
  Old behavior was nice for quick texturing -- in most cases you
  didn't need to modify texture space at all. But texture space
  was depending on render/preview settings which could easily lead
  to situations, when final result would be far different from
  preview one.
  Now we're using CV points coordinates and their radius to approximate
  the bounding box. This doesn't give the same exact texture space,
  but it helps a lot keeping texture space in a nice predictable way.
  We could make approximation smarter in the future, but fir now
  added operator to match texture space to fully tessellated curve
  called "Match Texture Space".
Review link:
  https://codereview.appspot.com/15410043/
Brief description:
  http://wiki.blender.org/index.php/User:Nazg-gul/GSoC-2013/Results#Curve_Texture_Space
											
										 
											2013-10-20 14:41:33 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int match_texture_space_exec(bContext *C, wmOperator *UNUSED(op)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Scene *scene = CTX_data_scene(C); | 
					
						
							|  |  |  | 	Object *object = CTX_data_active_object(C); | 
					
						
							|  |  |  | 	Curve *curve = (Curve *) object->data; | 
					
						
							|  |  |  | 	float min[3], max[3], size[3], loc[3]; | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-09 23:51:24 +06:00
										 |  |  | 	if (object->curve_cache == NULL) { | 
					
						
							| 
									
										
										
										
											2014-04-01 11:34:00 +11:00
										 |  |  | 		BKE_displist_make_curveTypes(scene, object, false); | 
					
						
							| 
									
										
											  
											
												Move curve's boundbox and texspace calculation out of modifier stack
There were several issues with how bounding box and texture space
are calculated:
- This was done at the same time as applying modifiers, meaning if
  several objects are sharing the same curve datablock, bounding
  box and texture space will be calculated multiple times.
  Further, allocating bounding box wasn't safe for threading.
- Bounding box and texture space were evaluated after pre-tessellation
  modifiers are applied. This means Curve-level data is actually
  depends on object data, and it's really bad because different
  objects could have different modifiers and this leads to
  conflicts (curve's data depends on object evaluation order)
  and doesn't behave in a predictable way.
  This commit moves bounding box and texture space evaluation from
  modifier stack to own utility functions, just like it's was done
  for meshes.
  This makes curve objects update thread-safe, but gives some
  limitations as well. Namely, with such approach it's not so
  clear how to preserve the same behavior of texture space:
  before this change texture space and bounding box would match
  beveled curve as accurate as possible.
  Old behavior was nice for quick texturing -- in most cases you
  didn't need to modify texture space at all. But texture space
  was depending on render/preview settings which could easily lead
  to situations, when final result would be far different from
  preview one.
  Now we're using CV points coordinates and their radius to approximate
  the bounding box. This doesn't give the same exact texture space,
  but it helps a lot keeping texture space in a nice predictable way.
  We could make approximation smarter in the future, but fir now
  added operator to match texture space to fully tessellated curve
  called "Match Texture Space".
Review link:
  https://codereview.appspot.com/15410043/
Brief description:
  http://wiki.blender.org/index.php/User:Nazg-gul/GSoC-2013/Results#Curve_Texture_Space
											
										 
											2013-10-20 14:41:33 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	INIT_MINMAX(min, max); | 
					
						
							|  |  |  | 	BKE_displist_minmax(&object->curve_cache->disp, min, max); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mid_v3_v3v3(loc, min, max); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	size[0] = (max[0] - min[0]) / 2.0f; | 
					
						
							|  |  |  | 	size[1] = (max[1] - min[1]) / 2.0f; | 
					
						
							|  |  |  | 	size[2] = (max[2] - min[2]) / 2.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (a = 0; a < 3; a++) { | 
					
						
							|  |  |  | 		if (size[a] == 0.0f) size[a] = 1.0f; | 
					
						
							|  |  |  | 		else if (size[a] > 0.0f && size[a] < 0.00001f) size[a] = 0.00001f; | 
					
						
							|  |  |  | 		else if (size[a] < 0.0f && size[a] > -0.00001f) size[a] = -0.00001f; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	copy_v3_v3(curve->loc, loc); | 
					
						
							|  |  |  | 	copy_v3_v3(curve->size, size); | 
					
						
							|  |  |  | 	zero_v3(curve->rot); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	curve->texflag &= ~CU_AUTOSPACE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, curve); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CURVE_OT_match_texture_space(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							|  |  |  | 	ot->name = "Match Texture Space"; | 
					
						
							|  |  |  | 	ot->idname = "CURVE_OT_match_texture_space"; | 
					
						
							|  |  |  | 	ot->description = "Match texture space to object's bounding box"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* api callbacks */ | 
					
						
							|  |  |  | 	ot->exec = match_texture_space_exec; | 
					
						
							|  |  |  | 	ot->poll = match_texture_space_poll; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							|  |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							|  |  |  | } |