2009-01-14 12:26:45 +00:00
|
|
|
/**
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* ***** 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 *****
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#ifndef WIN32
|
|
|
|
#include <unistd.h>
|
|
|
|
#else
|
|
|
|
#include <io.h>
|
|
|
|
#endif
|
|
|
|
#include <stdlib.h>
|
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"
|
2009-01-14 12:26:45 +00:00
|
|
|
#include "BLI_dynstr.h"
|
|
|
|
#include "BLI_rand.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2010-07-25 11:57:36 +00:00
|
|
|
#include "BLI_ghash.h"
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
#include "BKE_context.h"
|
|
|
|
#include "BKE_curve.h"
|
|
|
|
#include "BKE_depsgraph.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"
|
|
|
|
#include "BKE_library.h"
|
|
|
|
#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"
|
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
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
#include "UI_interface.h"
|
|
|
|
|
|
|
|
#include "RNA_access.h"
|
|
|
|
#include "RNA_define.h"
|
|
|
|
|
2010-04-30 04:48:40 +00:00
|
|
|
/* Undo stuff */
|
|
|
|
typedef struct {
|
|
|
|
ListBase nubase;
|
|
|
|
void *lastsel;
|
2010-07-25 11:57:36 +00:00
|
|
|
GHash *undoIndex;
|
2010-12-20 19:47:16 +00:00
|
|
|
ListBase fcurves;
|
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;
|
|
|
|
int key_index, nu_index, pt_index;
|
|
|
|
int switched;
|
|
|
|
Nurb *orig_nu;
|
|
|
|
} CVKeyIndex;
|
2010-07-25 11:57:36 +00:00
|
|
|
|
2009-11-29 22:16:29 +00:00
|
|
|
void selectend_nurb(Object *obedit, short selfirst, short doswap, short selstatus);
|
|
|
|
static void select_adjacent_cp(ListBase *editnurb, short next, short cont, short selstatus);
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
/* still need to eradicate a few :( */
|
|
|
|
#define callocstructN(x,y,name) (x*)MEM_callocN((y)* sizeof(x),name)
|
|
|
|
|
|
|
|
float nurbcircle[8][2]= {
|
|
|
|
{0.0, -1.0}, {-1.0, -1.0}, {-1.0, 0.0}, {-1.0, 1.0},
|
|
|
|
{0.0, 1.0}, { 1.0, 1.0}, { 1.0, 0.0}, { 1.0, -1.0}
|
|
|
|
};
|
|
|
|
|
|
|
|
ListBase *curve_get_editcurve(Object *ob)
|
|
|
|
{
|
|
|
|
if(ob && ELEM(ob->type, OB_CURVE, OB_SURF)) {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this replaces the active flag used in uv/face mode */
|
|
|
|
void set_actNurb(Object *obedit, Nurb *nu)
|
|
|
|
{
|
|
|
|
Curve *cu= obedit->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
|
|
|
if(nu==NULL)
|
2009-01-14 12:26:45 +00:00
|
|
|
cu->actnu = -1;
|
2010-07-25 11:57:36 +00:00
|
|
|
else {
|
|
|
|
ListBase *nurbs= ED_curve_editnurbs(cu);
|
|
|
|
cu->actnu = BLI_findindex(nurbs, nu);
|
|
|
|
}
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Nurb *get_actNurb(Object *obedit)
|
|
|
|
{
|
|
|
|
Curve *cu= obedit->data;
|
2010-07-25 11:57:36 +00:00
|
|
|
ListBase *nurbs= ED_curve_editnurbs(cu);
|
|
|
|
|
|
|
|
return BLI_findlink(nurbs, cu->actnu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************* SELECTION FUNCTIONS ********************* */
|
|
|
|
|
|
|
|
#define HIDDEN 1
|
|
|
|
#define VISIBLE 0
|
|
|
|
|
|
|
|
#define FIRST 1
|
|
|
|
#define LAST 0
|
|
|
|
|
|
|
|
|
|
|
|
/* returns 1 in case (de)selection was successful */
|
|
|
|
static short select_beztriple(BezTriple *bezt, short selstatus, short flag, short hidden)
|
|
|
|
{
|
|
|
|
if(bezt) {
|
|
|
|
if((bezt->hide==0) || (hidden==1)) {
|
|
|
|
if(selstatus==1) { /* selects */
|
|
|
|
bezt->f1 |= flag;
|
|
|
|
bezt->f2 |= flag;
|
|
|
|
bezt->f3 |= flag;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else { /* deselects */
|
|
|
|
bezt->f1 &= ~flag;
|
|
|
|
bezt->f2 &= ~flag;
|
|
|
|
bezt->f3 &= ~flag;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* returns 1 in case (de)selection was successful */
|
|
|
|
static short select_bpoint(BPoint *bp, short selstatus, short flag, short hidden)
|
|
|
|
{
|
|
|
|
if(bp) {
|
|
|
|
if((bp->hide==0) || (hidden==1)) {
|
|
|
|
if(selstatus==1) {
|
|
|
|
bp->f1 |= flag;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp->f1 &= ~flag;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static short swap_selection_beztriple(BezTriple *bezt)
|
|
|
|
{
|
|
|
|
if(bezt->f2 & SELECT)
|
|
|
|
return select_beztriple(bezt, DESELECT, 1, VISIBLE);
|
|
|
|
else
|
|
|
|
return select_beztriple(bezt, SELECT, 1, VISIBLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static short swap_selection_bpoint(BPoint *bp)
|
|
|
|
{
|
|
|
|
if(bp->f1 & SELECT)
|
|
|
|
return select_bpoint(bp, DESELECT, 1, VISIBLE);
|
|
|
|
else
|
|
|
|
return select_bpoint(bp, SELECT, 1, VISIBLE);
|
|
|
|
}
|
|
|
|
|
2009-06-24 14:07:48 +00:00
|
|
|
int isNurbsel(Nurb *nu)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
|
|
|
int a;
|
|
|
|
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a--) {
|
|
|
|
if( (bezt->f1 & SELECT) || (bezt->f2 & SELECT) || (bezt->f3 & SELECT) ) return 1;
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
while(a--) {
|
|
|
|
if( (bp->f1 & SELECT) ) return 1;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-09-08 07:35:07 +00:00
|
|
|
int isNurbsel_count(Curve *cu, Nurb *nu)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
|
|
|
int a, sel=0;
|
|
|
|
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a--) {
|
2009-09-08 07:35:07 +00:00
|
|
|
if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) sel++;
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
while(a--) {
|
|
|
|
if( (bp->f1 & SELECT) ) sel++;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return sel;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************* PRINTS ********************* */
|
|
|
|
|
|
|
|
void printknots(Object *obedit)
|
|
|
|
{
|
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
|
|
|
int a, num;
|
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
2009-09-08 00:23:33 +00:00
|
|
|
if(isNurbsel(nu) && nu->type == CU_NURBS) {
|
2009-01-14 12:26:45 +00:00
|
|
|
if(nu->knotsu) {
|
|
|
|
num= KNOTSU(nu);
|
|
|
|
for(a=0;a<num;a++) printf("knotu %d: %f\n", a, nu->knotsu[a]);
|
|
|
|
}
|
|
|
|
if(nu->knotsv) {
|
|
|
|
num= KNOTSV(nu);
|
|
|
|
for(a=0;a<num;a++) printf("knotv %d: %f\n", a, nu->knotsv[a]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-25 11:57:36 +00:00
|
|
|
/* ********************* Shape keys *************** */
|
|
|
|
|
2010-12-06 17:20:22 +00:00
|
|
|
static CVKeyIndex *init_cvKeyIndex(void *cv, int key_index, int nu_index, int pt_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
|
|
|
|
2010-12-06 17:20:22 +00:00
|
|
|
cvIndex->orig_cv= cv;
|
|
|
|
cvIndex->key_index= key_index;
|
|
|
|
cvIndex->nu_index= nu_index;
|
|
|
|
cvIndex->pt_index= pt_index;
|
|
|
|
cvIndex->switched= 0;
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2010-12-06 17:20:22 +00:00
|
|
|
static void free_cvKeyIndex(CVKeyIndex *pointIndex)
|
2010-07-25 11:57:36 +00:00
|
|
|
{
|
|
|
|
MEM_freeN(pointIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase)
|
|
|
|
{
|
|
|
|
Nurb *nu= editnurb->nurbs.first;
|
|
|
|
Nurb *orignu= origBase->first;
|
|
|
|
GHash *gh;
|
|
|
|
BezTriple *bezt, *origbezt;
|
|
|
|
BPoint *bp, *origbp;
|
2010-12-06 17:20:22 +00:00
|
|
|
CVKeyIndex *keyIndex;
|
|
|
|
int a, key_index= 0, nu_index= 0, pt_index= 0;
|
|
|
|
|
|
|
|
if(editnurb->keyindex) return;
|
2010-07-25 11:57:36 +00:00
|
|
|
|
|
|
|
gh= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "editNurb keyIndex");
|
|
|
|
|
|
|
|
while (orignu) {
|
|
|
|
if (orignu->bezt) {
|
|
|
|
a= orignu->pntsu;
|
|
|
|
bezt= nu->bezt;
|
|
|
|
origbezt= orignu->bezt;
|
2010-12-06 17:20:22 +00:00
|
|
|
pt_index= 0;
|
2010-07-25 11:57:36 +00:00
|
|
|
while (a--) {
|
2010-12-06 17:20:22 +00:00
|
|
|
keyIndex= init_cvKeyIndex(origbezt, key_index, nu_index, pt_index, orignu);
|
|
|
|
BLI_ghash_insert(gh, bezt, keyIndex);
|
|
|
|
key_index+= 12;
|
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
|
|
|
}
|
|
|
|
} else {
|
|
|
|
a= orignu->pntsu * orignu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
origbp= orignu->bp;
|
2010-12-06 17:20:22 +00:00
|
|
|
pt_index= 0;
|
2010-07-25 11:57:36 +00:00
|
|
|
while (a--) {
|
2010-12-06 17:20:22 +00:00
|
|
|
keyIndex= init_cvKeyIndex(origbp, key_index, nu_index, pt_index, orignu);
|
|
|
|
BLI_ghash_insert(gh, bp, keyIndex);
|
|
|
|
key_index+= 4;
|
2010-07-25 11:57:36 +00:00
|
|
|
bp++;
|
|
|
|
origbp++;
|
2010-12-06 17:20:22 +00:00
|
|
|
pt_index++;
|
2010-07-25 11:57:36 +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
|
|
|
}
|
|
|
|
|
|
|
|
editnurb->keyindex= gh;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_editNurb_keyIndex(EditNurb *editnurb)
|
|
|
|
{
|
|
|
|
if (!editnurb->keyindex) {
|
|
|
|
return;
|
|
|
|
}
|
2010-12-06 17:20:22 +00:00
|
|
|
BLI_ghash_free(editnurb->keyindex, NULL, (GHashValFreeFP)free_cvKeyIndex);
|
|
|
|
editnurb->keyindex= NULL;
|
2010-07-25 11:57:36 +00:00
|
|
|
}
|
|
|
|
|
2010-12-06 17:20:22 +00:00
|
|
|
static CVKeyIndex *getCVKeyIndex(EditNurb *editnurb, 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
|
|
|
}
|
|
|
|
|
2010-12-06 17:20:22 +00:00
|
|
|
static BezTriple *getKeyIndexOrig_bezt(EditNurb *editnurb, BezTriple *bezt)
|
2010-07-25 11:57:36 +00:00
|
|
|
{
|
2010-12-06 17:20:22 +00:00
|
|
|
CVKeyIndex *index= getCVKeyIndex(editnurb, bezt);
|
2010-07-25 11:57:36 +00:00
|
|
|
|
|
|
|
if (!index) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-12-06 17:20:22 +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
|
|
|
{
|
2010-12-06 17:20:22 +00:00
|
|
|
CVKeyIndex *index= getCVKeyIndex(editnurb, bp);
|
2010-07-25 11:57:36 +00:00
|
|
|
|
|
|
|
if (!index) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-12-06 17:20:22 +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
|
|
|
{
|
2010-12-06 17:20:22 +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
|
|
|
}
|
|
|
|
|
2010-12-06 17:20:22 +00:00
|
|
|
static void keyIndex_delCV(EditNurb *editnurb, void *cv)
|
2010-07-25 11:57:36 +00:00
|
|
|
{
|
|
|
|
if (!editnurb->keyindex) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-12-06 17:20:22 +00:00
|
|
|
BLI_ghash_remove(editnurb->keyindex, cv, NULL, (GHashValFreeFP)free_cvKeyIndex);
|
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) {
|
|
|
|
BezTriple *bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
|
|
|
|
while (a--) {
|
2010-12-06 17:20:22 +00:00
|
|
|
BLI_ghash_remove(editnurb->keyindex, bezt, NULL, (GHashValFreeFP)free_cvKeyIndex);
|
2010-07-25 11:57:36 +00:00
|
|
|
++bezt;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
BPoint *bp= nu->bp;
|
|
|
|
a= nu->pntsu * nu->pntsv;
|
|
|
|
|
|
|
|
while (a--) {
|
2010-12-06 17:20:22 +00:00
|
|
|
BLI_ghash_remove(editnurb->keyindex, bp, NULL, (GHashValFreeFP)free_cvKeyIndex);
|
2010-07-25 11:57:36 +00:00
|
|
|
++bp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void keyIndex_delNurbList(EditNurb *editnurb, ListBase *nubase)
|
|
|
|
{
|
|
|
|
Nurb *nu= nubase->first;
|
|
|
|
|
|
|
|
while (nu) {
|
|
|
|
keyIndex_delNurb(editnurb, nu);
|
|
|
|
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-06 17:20:22 +00:00
|
|
|
static void keyIndex_updateCV(EditNurb *editnurb, char *cv,
|
2010-12-06 21:18:08 +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++) {
|
2010-12-06 21:18:08 +00:00
|
|
|
index= getCVKeyIndex(editnurb, cv);
|
2010-07-25 11:57:36 +00:00
|
|
|
|
2010-12-06 17:20:22 +00:00
|
|
|
BLI_ghash_remove(editnurb->keyindex, cv, NULL, NULL);
|
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,
|
2010-12-06 21:18:08 +00:00
|
|
|
BezTriple *newbezt, int count)
|
2010-07-25 11:57:36 +00:00
|
|
|
{
|
2010-12-06 21:18:08 +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,
|
2010-12-06 21:18:08 +00:00
|
|
|
BPoint *newbp, int count)
|
2010-07-25 11:57:36 +00:00
|
|
|
{
|
2010-12-06 21:18:08 +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);
|
2010-07-25 11:57:36 +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)
|
|
|
|
{
|
2010-12-06 17:20:22 +00:00
|
|
|
CVKeyIndex *index1= getCVKeyIndex(editnurb, a);
|
|
|
|
CVKeyIndex *index2= getCVKeyIndex(editnurb, b);
|
2010-07-25 11:57:36 +00:00
|
|
|
|
|
|
|
BLI_ghash_remove(editnurb->keyindex, a, NULL, NULL);
|
|
|
|
BLI_ghash_remove(editnurb->keyindex, b, NULL, NULL);
|
|
|
|
|
2010-12-06 13:44:36 +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;
|
|
|
|
|
|
|
|
a= nu->pntsu;
|
|
|
|
|
|
|
|
bezt1= nu->bezt;
|
|
|
|
bezt2= bezt1+(a-1);
|
|
|
|
|
|
|
|
if (a & 1) ++a;
|
|
|
|
|
|
|
|
a/=2;
|
|
|
|
|
|
|
|
while (a--) {
|
2010-12-06 17:20:22 +00:00
|
|
|
index1= getCVKeyIndex(editnurb, bezt1);
|
|
|
|
index2= getCVKeyIndex(editnurb, bezt2);
|
|
|
|
|
|
|
|
if(index1) index1->switched= !index1->switched;
|
|
|
|
|
2010-07-25 11:57:36 +00:00
|
|
|
if (bezt1 != bezt2) {
|
|
|
|
keyIndex_swap(editnurb, bezt1, bezt2);
|
2010-12-06 17:20:22 +00:00
|
|
|
|
|
|
|
if(index2) index2->switched= !index2->switched;
|
2010-07-25 11:57:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bezt1++;
|
|
|
|
bezt2--;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
BPoint *bp1, *bp2;
|
|
|
|
|
|
|
|
if (nu->pntsv == 1) {
|
|
|
|
a= nu->pntsu;
|
|
|
|
bp1= nu->bp;
|
|
|
|
bp2= bp1+(a-1);
|
|
|
|
a/= 2;
|
|
|
|
while(bp1!=bp2 && a>0) {
|
2010-12-06 17:20:22 +00:00
|
|
|
index1= getCVKeyIndex(editnurb, bp1);
|
|
|
|
index2= getCVKeyIndex(editnurb, bp2);
|
|
|
|
|
|
|
|
if(index1) index1->switched= !index1->switched;
|
|
|
|
|
2010-07-25 11:57:36 +00:00
|
|
|
if (bp1 != bp2) {
|
2010-12-06 17:20:22 +00:00
|
|
|
if(index2) index2->switched= !index2->switched;
|
|
|
|
|
2010-07-25 11:57:36 +00:00
|
|
|
keyIndex_swap(editnurb, bp1, bp2);
|
|
|
|
}
|
|
|
|
|
|
|
|
a--;
|
|
|
|
bp1++;
|
|
|
|
bp2--;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
int b;
|
|
|
|
|
|
|
|
for(b=0; b<nu->pntsv; b++) {
|
|
|
|
|
|
|
|
bp1= nu->bp+b*nu->pntsu;
|
|
|
|
a= nu->pntsu;
|
|
|
|
bp2= bp1+(a-1);
|
|
|
|
a/= 2;
|
|
|
|
|
|
|
|
while(bp1!=bp2 && a>0) {
|
2010-12-06 17:20:22 +00:00
|
|
|
index1= getCVKeyIndex(editnurb, bp1);
|
|
|
|
index2= getCVKeyIndex(editnurb, bp2);
|
|
|
|
|
|
|
|
if(index1) index1->switched= !index1->switched;
|
|
|
|
|
2010-07-25 11:57:36 +00:00
|
|
|
if (bp1 != bp2) {
|
2010-12-06 17:20:22 +00:00
|
|
|
if(index2) index2->switched= !index2->switched;
|
|
|
|
|
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;
|
2010-12-06 13:44:36 +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;
|
|
|
|
while(currkey) {
|
|
|
|
fp= currkey->data;
|
|
|
|
|
|
|
|
nu= nubase->first;
|
|
|
|
while (nu) {
|
|
|
|
if (nu->bezt) {
|
2010-12-06 13:44:36 +00:00
|
|
|
BezTriple *bezt= nu->bezt;
|
2010-07-25 11:57:36 +00:00
|
|
|
a= nu->pntsu;
|
|
|
|
if (nu == actnu) {
|
|
|
|
while (a--) {
|
2010-12-06 13:44:36 +00:00
|
|
|
if(getKeyIndexOrig_bezt(editnurb, bezt)) {
|
|
|
|
swap_v3_v3(fp, fp + 6);
|
|
|
|
*(fp+9) = -*(fp+9);
|
|
|
|
fp += 12;
|
|
|
|
}
|
|
|
|
bezt++;
|
2010-07-25 11:57:36 +00:00
|
|
|
}
|
|
|
|
} else fp += a * 12;
|
|
|
|
} else {
|
2010-12-06 13:44:36 +00:00
|
|
|
BPoint *bp= nu->bp;
|
2010-07-25 11:57:36 +00:00
|
|
|
a= nu->pntsu * nu->pntsv;
|
|
|
|
if (nu == actnu) {
|
|
|
|
while (a--) {
|
2010-12-06 13:44:36 +00:00
|
|
|
if(getKeyIndexOrig_bp(editnurb, bp)) {
|
|
|
|
*(fp+3) = -*(fp+3);
|
|
|
|
fp += 4;
|
|
|
|
}
|
|
|
|
bp++;
|
2010-07-25 11:57:36 +00:00
|
|
|
}
|
|
|
|
} else fp += a * 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
currkey= currkey->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void keyData_switchDirectionNurb(Curve *cu, Nurb *nu)
|
|
|
|
{
|
|
|
|
EditNurb *editnurb= cu->editnurb;
|
|
|
|
|
|
|
|
if (!editnurb->keyindex) {
|
|
|
|
/* no shape keys - nothing to do */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
keyIndex_switchDirection(editnurb, nu);
|
2010-12-06 17:20:22 +00:00
|
|
|
if(cu->key)
|
|
|
|
switch_keys_direction(cu, nu);
|
2010-07-25 11:57:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static GHash *dupli_keyIndexHash(GHash *keyindex)
|
|
|
|
{
|
|
|
|
GHash *gh;
|
|
|
|
GHashIterator *hashIter;
|
|
|
|
|
|
|
|
gh= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "dupli_keyIndex gh");
|
|
|
|
|
|
|
|
for(hashIter = BLI_ghashIterator_new(keyindex);
|
|
|
|
!BLI_ghashIterator_isDone(hashIter);
|
|
|
|
BLI_ghashIterator_step(hashIter)) {
|
2010-12-06 17:20:22 +00:00
|
|
|
void *cv = BLI_ghashIterator_getKey(hashIter);
|
|
|
|
CVKeyIndex *index = BLI_ghashIterator_getValue(hashIter);
|
|
|
|
CVKeyIndex *newIndex = MEM_callocN(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
|
|
|
}
|
|
|
|
|
|
|
|
BLI_ghashIterator_free(hashIter);
|
|
|
|
|
|
|
|
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);
|
|
|
|
bezt->alfa= key[9];
|
|
|
|
}
|
|
|
|
|
|
|
|
static void bezt_to_key(BezTriple *bezt, float *key)
|
|
|
|
{
|
|
|
|
memcpy(key, bezt->vec, sizeof(float) * 9);
|
|
|
|
key[9] = bezt->alfa;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void calc_keyHandles(ListBase *nurb, float *key)
|
|
|
|
{
|
|
|
|
Nurb *nu;
|
|
|
|
int a;
|
|
|
|
float *fp= key;
|
|
|
|
BezTriple *bezt;
|
|
|
|
|
|
|
|
nu= nurb->first;
|
|
|
|
while (nu) {
|
|
|
|
if (nu->bezt) {
|
|
|
|
BezTriple *prevp, *nextp;
|
|
|
|
BezTriple cur, prev, next;
|
|
|
|
float *startfp, *prevfp, *nextfp;
|
|
|
|
|
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
startfp= fp;
|
|
|
|
|
|
|
|
if(nu->flagu & CU_NURB_CYCLIC) {
|
|
|
|
prevp= bezt+(a-1);
|
|
|
|
prevfp= fp+(12 * (a-1));
|
|
|
|
} else {
|
|
|
|
prevp= NULL;
|
|
|
|
prevfp= NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
nextp= bezt + 1;
|
|
|
|
nextfp= fp + 12;
|
|
|
|
|
|
|
|
while (a--) {
|
|
|
|
key_to_bezt(fp, bezt, &cur);
|
|
|
|
|
|
|
|
if (nextp) key_to_bezt(nextfp, nextp, &next);
|
|
|
|
if (prevp) key_to_bezt(prevfp, prevp, &prev);
|
|
|
|
|
|
|
|
calchandleNurb(&cur, prevp ? &prev : NULL, nextp ? &next : NULL, 0);
|
|
|
|
bezt_to_key(&cur, fp);
|
|
|
|
|
|
|
|
prevp= bezt;
|
|
|
|
prevfp= fp;
|
|
|
|
if(a==1) {
|
|
|
|
if(nu->flagu & CU_NURB_CYCLIC) {
|
|
|
|
nextp= nu->bezt;
|
|
|
|
nextfp= startfp;
|
|
|
|
} else {
|
|
|
|
nextp= NULL;
|
|
|
|
nextfp= NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
++nextp;
|
2010-12-03 01:52:28 +00:00
|
|
|
nextfp += 12;
|
2010-07-25 11:57:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
++bezt;
|
|
|
|
fp += 12;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
a= nu->pntsu * nu->pntsv;
|
|
|
|
fp += a * 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void calc_shapeKeys(Object *obedit)
|
|
|
|
{
|
|
|
|
Curve *cu= (Curve*)obedit->data;
|
|
|
|
|
|
|
|
/* are there keys? */
|
|
|
|
if(cu->key) {
|
|
|
|
int a, i, j;
|
|
|
|
EditNurb *editnurb= cu->editnurb;
|
|
|
|
KeyBlock *currkey;
|
2010-08-10 06:36:42 +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;
|
|
|
|
int totvert= count_curveverts(&editnurb->nurbs);
|
|
|
|
|
|
|
|
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 */
|
|
|
|
if(cu->key->type==KEY_RELATIVE) {
|
|
|
|
int act_is_basis = 0;
|
|
|
|
/* find if this key is a basis for any others */
|
|
|
|
for(currkey = cu->key->block.first; currkey; currkey= currkey->next) {
|
2010-08-10 06:36:42 +00:00
|
|
|
if(editnurb->shapenr-1 == currkey->relative) {
|
2010-07-25 11:57:36 +00:00
|
|
|
act_is_basis = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(act_is_basis) { /* active key is a base */
|
|
|
|
int j;
|
|
|
|
int totvec= 0;
|
|
|
|
|
|
|
|
/* Calculate needed memory to store offset */
|
|
|
|
nu= editnurb->nurbs.first;
|
|
|
|
while(nu) {
|
|
|
|
if (nu->bezt) {
|
|
|
|
/* Three vects to store handles and one for alfa */
|
|
|
|
totvec+= nu->pntsu * 4;
|
|
|
|
} else {
|
|
|
|
totvec+= 2 * nu->pntsu * nu->pntsv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
ofs= MEM_callocN(sizeof(float) * 3 * totvec, "currkey->data");
|
|
|
|
nu= editnurb->nurbs.first;
|
|
|
|
i= 0;
|
|
|
|
while(nu) {
|
|
|
|
if(nu->bezt) {
|
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a--) {
|
|
|
|
oldbezt= getKeyIndexOrig_bezt(editnurb, bezt);
|
|
|
|
|
|
|
|
if (oldbezt) {
|
|
|
|
for (j= 0; j < 3; ++j) {
|
|
|
|
VECSUB(ofs[i], bezt->vec[j], oldbezt->vec[j]);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
ofs[i++][0]= bezt->alfa - oldbezt->alfa;
|
|
|
|
} else {
|
|
|
|
i += 4;
|
|
|
|
}
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
while(a--) {
|
|
|
|
oldbp= getKeyIndexOrig_bp(editnurb, bp);
|
|
|
|
if (oldbp) {
|
|
|
|
VECSUB(ofs[i], bp->vec, oldbp->vec);
|
|
|
|
ofs[i+1][0]= bp->alfa - oldbp->alfa;
|
|
|
|
}
|
|
|
|
i += 2;
|
|
|
|
++bp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
currkey = cu->key->block.first;
|
|
|
|
while(currkey) {
|
2010-08-10 06:36:42 +00:00
|
|
|
int apply_offset = (ofs && (currkey != actkey) && (editnurb->shapenr-1 == currkey->relative));
|
2010-07-25 11:57:36 +00:00
|
|
|
|
2010-10-07 10:04:07 +00:00
|
|
|
float *fp= newkey= MEM_callocN(cu->key->elemsize * totvert, "currkey->data");
|
2010-07-25 11:57:36 +00:00
|
|
|
ofp= oldkey = currkey->data;
|
|
|
|
|
|
|
|
nu= editnurb->nurbs.first;
|
|
|
|
i = 0;
|
|
|
|
while(nu) {
|
|
|
|
if(currkey == actkey) {
|
|
|
|
int restore= actkey != cu->key->refkey;
|
|
|
|
|
|
|
|
if(nu->bezt) {
|
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a--) {
|
|
|
|
oldbezt= getKeyIndexOrig_bezt(editnurb, bezt);
|
|
|
|
|
|
|
|
for (j= 0; j < 3; ++j, ++i) {
|
|
|
|
VECCOPY(fp, bezt->vec[j]);
|
|
|
|
|
|
|
|
if (restore && oldbezt) {
|
|
|
|
VECCOPY(bezt->vec[j], oldbezt->vec[j]);
|
|
|
|
}
|
|
|
|
|
|
|
|
fp+= 3;
|
|
|
|
}
|
|
|
|
fp[0]= bezt->alfa;
|
|
|
|
|
|
|
|
if(restore && oldbezt) {
|
|
|
|
bezt->alfa= oldbezt->alfa;
|
|
|
|
}
|
|
|
|
|
|
|
|
fp+= 3; ++i;/* alphas */
|
|
|
|
++bezt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
while(a--) {
|
|
|
|
oldbp= getKeyIndexOrig_bp(editnurb, bp);
|
|
|
|
|
|
|
|
VECCOPY(fp, bp->vec);
|
|
|
|
|
|
|
|
fp[3]= bp->alfa;
|
|
|
|
|
|
|
|
if(restore && oldbp) {
|
|
|
|
VECCOPY(bp->vec, oldbp->vec);
|
|
|
|
bp->alfa= oldbp->alfa;
|
|
|
|
}
|
|
|
|
|
|
|
|
fp+= 4;
|
|
|
|
++bp;
|
|
|
|
i+=2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
int index;
|
|
|
|
float *curofp;
|
|
|
|
|
|
|
|
if(oldkey) {
|
|
|
|
if(nu->bezt) {
|
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
|
|
|
|
while(a--) {
|
2010-12-06 17:20:22 +00:00
|
|
|
index= getKeyIndexOrig_keyIndex(editnurb, bezt);
|
2010-07-25 11:57:36 +00:00
|
|
|
if (index >= 0) {
|
|
|
|
curofp= ofp + index;
|
|
|
|
|
|
|
|
for (j= 0; j < 3; ++j, ++i) {
|
|
|
|
VECCOPY(fp, curofp);
|
|
|
|
|
|
|
|
if(apply_offset) {
|
|
|
|
VECADD(fp, fp, ofs[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
fp+= 3; curofp+= 3;
|
|
|
|
}
|
2010-07-26 19:07:33 +00:00
|
|
|
fp[0]= curofp[0];
|
2010-07-25 11:57:36 +00:00
|
|
|
|
|
|
|
if(apply_offset) {
|
|
|
|
/* apply alfa offsets */
|
|
|
|
VECADD(fp, fp, ofs[i]);
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
fp+= 3; curofp+= 3; /* alphas */
|
|
|
|
} else {
|
|
|
|
for (j= 0; j < 3; ++j, ++i) {
|
|
|
|
VECCOPY(fp, bezt->vec[j]);
|
|
|
|
fp+= 3;
|
|
|
|
}
|
|
|
|
fp[0]= bezt->alfa;
|
|
|
|
|
|
|
|
fp+= 3; /* alphas */
|
|
|
|
}
|
|
|
|
++bezt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
while(a--) {
|
2010-12-06 17:20:22 +00:00
|
|
|
index= getKeyIndexOrig_keyIndex(editnurb, bp);
|
2010-07-25 11:57:36 +00:00
|
|
|
|
|
|
|
if (index >= 0) {
|
|
|
|
curofp= ofp + index;
|
|
|
|
VECCOPY(fp, curofp);
|
2010-07-26 19:07:33 +00:00
|
|
|
fp[3]= curofp[3];
|
2010-07-25 11:57:36 +00:00
|
|
|
|
|
|
|
if(apply_offset) {
|
|
|
|
VECADD(fp, fp, ofs[i]);
|
|
|
|
fp[3]+=ofs[i+1][0];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
VECCOPY(fp, bp->vec);
|
|
|
|
fp[3]= bp->alfa;
|
|
|
|
}
|
|
|
|
|
|
|
|
fp+= 4;
|
|
|
|
++bp;
|
|
|
|
i+=2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (apply_offset) {
|
|
|
|
/* handles could become malicious after offsets applying */
|
|
|
|
calc_keyHandles(&editnurb->nurbs, newkey);
|
|
|
|
}
|
|
|
|
|
|
|
|
currkey->totelem= totvert;
|
|
|
|
if(currkey->data) MEM_freeN(currkey->data);
|
|
|
|
currkey->data = newkey;
|
|
|
|
|
|
|
|
currkey= currkey->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ofs) MEM_freeN(ofs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-06 17:20:22 +00:00
|
|
|
/* ********************* Amimation data *************** */
|
|
|
|
|
|
|
|
static int curve_is_animated(Object *ob)
|
|
|
|
{
|
|
|
|
Curve *cu= (Curve*)ob->data;
|
|
|
|
AnimData *ad= BKE_animdata_from_id(&cu->id);
|
|
|
|
|
|
|
|
return ad && ad->action;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fcurve_path_rename(char *orig_rna_path, char *rna_path, ListBase *orig_curves, ListBase *curves)
|
|
|
|
{
|
|
|
|
FCurve *fcu, *nfcu, *nextfcu;
|
|
|
|
int len= strlen(orig_rna_path);
|
|
|
|
|
|
|
|
fcu= orig_curves->first;
|
|
|
|
while (fcu) {
|
|
|
|
nextfcu= fcu->next;
|
|
|
|
if(!strncmp(fcu->rna_path, orig_rna_path, len)) {
|
|
|
|
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);
|
|
|
|
BLI_addtail(curves, nfcu);
|
|
|
|
|
|
|
|
BLI_remlink(orig_curves, fcu);
|
|
|
|
free_fcurve(fcu);
|
|
|
|
|
|
|
|
MEM_freeN(spath);
|
|
|
|
}
|
|
|
|
fcu= nextfcu;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-20 19:47:16 +00:00
|
|
|
/* return 0 if animation data wasn't changed, 1 otherwise */
|
|
|
|
int ED_curve_updateAnimPaths(Object *obedit)
|
2010-12-06 17:20:22 +00:00
|
|
|
{
|
|
|
|
int nu_index= 0, a, pt_index;
|
|
|
|
Curve *cu= (Curve*)obedit->data;
|
|
|
|
EditNurb *editnurb= cu->editnurb;
|
|
|
|
Nurb *nu= editnurb->nurbs.first;
|
|
|
|
CVKeyIndex *keyIndex;
|
|
|
|
char rna_path[64], orig_rna_path[64];
|
|
|
|
ListBase orig_curves= {0, 0};
|
|
|
|
ListBase curves= {0, 0};
|
|
|
|
AnimData *ad= BKE_animdata_from_id(&cu->id);
|
2010-12-20 19:47:16 +00:00
|
|
|
FCurve *fcu, *next;
|
2010-12-06 17:20:22 +00:00
|
|
|
|
2010-12-20 19:47:16 +00:00
|
|
|
if(!curve_is_animated(obedit)) return 0;
|
2010-12-06 17:20:22 +00:00
|
|
|
|
2010-12-20 19:47:16 +00:00
|
|
|
copy_fcurves(&orig_curves, &ad->action->curves);
|
2010-12-06 17:20:22 +00:00
|
|
|
|
|
|
|
while(nu) {
|
|
|
|
if(nu->bezt) {
|
|
|
|
BezTriple *bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
pt_index= 0;
|
|
|
|
|
|
|
|
while (a--) {
|
|
|
|
keyIndex= getCVKeyIndex(editnurb, bezt);
|
|
|
|
if(keyIndex) {
|
|
|
|
sprintf(rna_path, "splines[%d].bezier_points[%d]", nu_index, pt_index);
|
|
|
|
sprintf(orig_rna_path, "splines[%d].bezier_points[%d]", keyIndex->nu_index, keyIndex->pt_index);
|
|
|
|
|
|
|
|
if(keyIndex->switched) {
|
|
|
|
char handle_path[64], orig_handle_path[64];
|
|
|
|
sprintf(orig_handle_path, "%s.handle_left", orig_rna_path);
|
|
|
|
sprintf(handle_path, "%s.handle_right", rna_path);
|
|
|
|
fcurve_path_rename(orig_handle_path, handle_path, &orig_curves, &curves);
|
|
|
|
|
|
|
|
sprintf(orig_handle_path, "%s.handle_right", orig_rna_path);
|
|
|
|
sprintf(handle_path, "%s.handle_left", rna_path);
|
|
|
|
fcurve_path_rename(orig_handle_path, handle_path, &orig_curves, &curves);
|
|
|
|
}
|
|
|
|
|
|
|
|
fcurve_path_rename(orig_rna_path, rna_path, &orig_curves, &curves);
|
2010-12-20 19:47:16 +00:00
|
|
|
|
|
|
|
keyIndex->nu_index= nu_index;
|
|
|
|
keyIndex->pt_index= pt_index;
|
2010-12-06 17:20:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bezt++;
|
|
|
|
pt_index++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
BPoint *bp= nu->bp;
|
|
|
|
a= nu->pntsu * nu->pntsv;
|
|
|
|
pt_index= 0;
|
|
|
|
|
|
|
|
while (a--) {
|
|
|
|
keyIndex= getCVKeyIndex(editnurb, bp);
|
|
|
|
if(keyIndex) {
|
|
|
|
sprintf(rna_path, "splines[%d].points[%d]", nu_index, pt_index);
|
|
|
|
sprintf(orig_rna_path, "splines[%d].points[%d]", keyIndex->nu_index, keyIndex->pt_index);
|
|
|
|
fcurve_path_rename(orig_rna_path, rna_path, &orig_curves, &curves);
|
2010-12-20 19:47:16 +00:00
|
|
|
|
|
|
|
keyIndex->nu_index= nu_index;
|
|
|
|
keyIndex->pt_index= pt_index;
|
2010-12-06 17:20:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bp++;
|
|
|
|
pt_index++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nu= nu->next;
|
|
|
|
nu_index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
nu_index= 0;
|
|
|
|
while(nu) {
|
|
|
|
if(keyIndex) {
|
|
|
|
sprintf(rna_path, "splines[%d]", nu_index);
|
|
|
|
sprintf(orig_rna_path, "splines[%d]", keyIndex->nu_index);
|
|
|
|
fcurve_path_rename(orig_rna_path, rna_path, &ad->action->curves, &curves);
|
|
|
|
}
|
|
|
|
nu_index++;
|
|
|
|
}
|
|
|
|
|
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) */
|
|
|
|
for(fcu= orig_curves.first; fcu; fcu= next) {
|
|
|
|
next= fcu->next;
|
|
|
|
|
|
|
|
if(!strncmp(fcu->rna_path, "splines", 7)) free_fcurve(fcu);
|
|
|
|
else BLI_addtail(&curves, fcu);
|
|
|
|
}
|
2010-12-13 17:10:44 +00:00
|
|
|
|
2010-12-06 17:20:22 +00:00
|
|
|
free_fcurves(&ad->action->curves);
|
|
|
|
ad->action->curves= curves;
|
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 *************** */
|
|
|
|
|
|
|
|
/* load editNurb in object */
|
|
|
|
void load_editNurb(Object *obedit)
|
|
|
|
{
|
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
|
|
|
|
if(obedit==NULL) return;
|
|
|
|
|
2009-09-08 07:35:07 +00:00
|
|
|
set_actNurb(obedit, NULL);
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
|
|
|
|
Curve *cu= obedit->data;
|
|
|
|
Nurb *nu, *newnu;
|
2010-07-25 11:57:36 +00:00
|
|
|
ListBase newnurb= {NULL, NULL}, oldnurb= cu->nurb;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-07-25 11:57:36 +00:00
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
newnu= duplicateNurb(nu);
|
|
|
|
BLI_addtail(&newnurb, newnu);
|
|
|
|
|
|
|
|
if(nu->type == CU_NURBS) {
|
|
|
|
clamp_nurb_order_u(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
2010-07-25 11:57:36 +00:00
|
|
|
|
|
|
|
cu->nurb= newnurb;
|
|
|
|
|
|
|
|
calc_shapeKeys(obedit);
|
2010-12-06 17:20:22 +00:00
|
|
|
ED_curve_updateAnimPaths(obedit);
|
2010-07-25 11:57:36 +00:00
|
|
|
|
|
|
|
freeNurblist(&oldnurb);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
2010-07-25 11:57:36 +00:00
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
set_actNurb(obedit, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* make copy in cu->editnurb */
|
|
|
|
void make_editNurb(Object *obedit)
|
|
|
|
{
|
2010-07-25 11:57:36 +00:00
|
|
|
Curve *cu= (Curve*)obedit->data;
|
|
|
|
EditNurb *editnurb= cu->editnurb;
|
2009-09-08 07:35:07 +00:00
|
|
|
Nurb *nu, *newnu, *nu_act= NULL;
|
2009-01-14 12:26:45 +00:00
|
|
|
KeyBlock *actkey;
|
2010-12-06 17:20:22 +00:00
|
|
|
int is_anim;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
if(obedit==NULL) return;
|
|
|
|
|
2009-09-08 07:35:07 +00:00
|
|
|
set_actNurb(obedit, NULL);
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
|
2010-12-06 17:20:22 +00:00
|
|
|
actkey= ob_get_keyblock(obedit);
|
|
|
|
is_anim= curve_is_animated(obedit);
|
|
|
|
|
2010-07-25 11:57:36 +00:00
|
|
|
if(actkey) {
|
|
|
|
// XXX strcpy(G.editModeTitleExtra, "(Key) ");
|
|
|
|
undo_editmode_clear();
|
|
|
|
key_to_curve(actkey, cu, &cu->nurb);
|
|
|
|
}
|
|
|
|
|
2010-12-06 17:20:22 +00:00
|
|
|
if (is_anim) {
|
|
|
|
undo_editmode_clear();
|
|
|
|
}
|
|
|
|
|
2010-07-25 11:57:36 +00:00
|
|
|
if(editnurb) {
|
|
|
|
freeNurblist(&editnurb->nurbs);
|
|
|
|
free_editNurb_keyIndex(editnurb);
|
|
|
|
editnurb->keyindex= NULL;
|
|
|
|
} else {
|
|
|
|
editnurb= MEM_callocN(sizeof(EditNurb), "editnurb");
|
|
|
|
cu->editnurb= editnurb;
|
|
|
|
}
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
nu= cu->nurb.first;
|
2010-04-30 04:48:40 +00:00
|
|
|
cu->lastsel= NULL; /* for select row */
|
2010-07-25 11:57:36 +00:00
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
while(nu) {
|
|
|
|
newnu= duplicateNurb(nu);
|
|
|
|
test2DNurb(newnu); // after join, or any other creation of curve
|
2010-07-25 11:57:36 +00:00
|
|
|
BLI_addtail(&editnurb->nurbs, newnu);
|
2009-09-08 07:35:07 +00:00
|
|
|
|
|
|
|
if (nu_act == NULL && isNurbsel(nu)) {
|
|
|
|
nu_act= newnu;
|
|
|
|
set_actNurb(obedit, newnu);
|
|
|
|
}
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
nu= nu->next;
|
|
|
|
}
|
2010-07-25 11:57:36 +00:00
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
if(actkey) {
|
2010-08-10 06:36:42 +00:00
|
|
|
editnurb->shapenr= obedit->shapenr;
|
2010-07-25 11:57:36 +00:00
|
|
|
init_editNurb_keyIndex(editnurb, &cu->nurb);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
2010-12-06 17:20:22 +00:00
|
|
|
|
2010-12-20 19:47:16 +00:00
|
|
|
if(is_anim)
|
2010-12-06 17:20:22 +00:00
|
|
|
init_editNurb_keyIndex(editnurb, &cu->nurb);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-25 11:57:36 +00:00
|
|
|
void free_curve_editNurb (Curve *cu)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
|
|
|
if(cu->editnurb) {
|
2010-07-25 11:57:36 +00:00
|
|
|
freeNurblist(&cu->editnurb->nurbs);
|
|
|
|
free_editNurb_keyIndex(cu->editnurb);
|
2009-01-14 12:26:45 +00:00
|
|
|
MEM_freeN(cu->editnurb);
|
|
|
|
cu->editnurb= NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-25 11:57:36 +00:00
|
|
|
void free_editNurb(Object *obedit)
|
|
|
|
{
|
|
|
|
Curve *cu= obedit->data;
|
|
|
|
|
|
|
|
free_curve_editNurb(cu);
|
|
|
|
}
|
|
|
|
|
2009-11-29 22:16:29 +00:00
|
|
|
void CU_deselect_all(Object *obedit)
|
|
|
|
{
|
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
|
|
|
|
if (editnurb) {
|
|
|
|
selectend_nurb(obedit, FIRST, 0, DESELECT); /* set first control points as unselected */
|
|
|
|
select_adjacent_cp(editnurb, 1, 1, DESELECT); /* cascade selection */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CU_select_all(Object *obedit)
|
|
|
|
{
|
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
|
|
|
|
if (editnurb) {
|
2009-11-30 12:50:22 +00:00
|
|
|
selectend_nurb(obedit, FIRST, 0, SELECT); /* set first control points as unselected */
|
|
|
|
select_adjacent_cp(editnurb, 1, 1, SELECT); /* cascade selection */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CU_select_swap(Object *obedit)
|
|
|
|
{
|
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
|
|
|
|
if (editnurb) {
|
|
|
|
Curve *cu= obedit->data;
|
|
|
|
Nurb *nu;
|
|
|
|
BPoint *bp;
|
|
|
|
BezTriple *bezt;
|
|
|
|
int a;
|
|
|
|
|
2010-04-30 04:48:40 +00:00
|
|
|
cu->lastsel= NULL;
|
|
|
|
|
2009-11-30 12:50:22 +00:00
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
if(nu->type == CU_BEZIER) {
|
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a--) {
|
|
|
|
if(bezt->hide==0) {
|
|
|
|
bezt->f2 ^= SELECT; /* always do the center point */
|
|
|
|
if((cu->drawflag & CU_HIDE_HANDLES)==0) {
|
|
|
|
bezt->f1 ^= SELECT;
|
|
|
|
bezt->f3 ^= SELECT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
while(a--) {
|
|
|
|
swap_selection_bpoint(bp);
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-11-29 22:16:29 +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
|
|
|
{
|
2010-08-01 12:47:49 +00:00
|
|
|
Main *bmain= CTX_data_main(C);
|
2009-02-11 23:02:21 +00:00
|
|
|
Scene *scene= CTX_data_scene(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
Nurb *nu, *nu1;
|
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;
|
2010-07-25 11:57:36 +00:00
|
|
|
EditNurb *oldedit, *newedit;
|
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
|
|
|
|
|
|
|
oldbase= CTX_data_active_base(C);
|
|
|
|
oldob= oldbase->object;
|
|
|
|
oldcu= oldob->data;
|
|
|
|
oldedit= oldcu->editnurb;
|
|
|
|
|
|
|
|
if(oldcu->key) {
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "Can't 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);
|
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
|
|
|
/* 1. duplicate the object and data */
|
2010-08-01 12:47:49 +00:00
|
|
|
newbase= ED_object_add_duplicate(bmain, scene, oldbase, 0); /* 0 = fully linked */
|
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
|
|
|
ED_base_object_select(newbase, BA_DESELECT);
|
|
|
|
newob= newbase->object;
|
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
|
|
|
newcu= newob->data= copy_curve(oldcu);
|
|
|
|
newcu->editnurb= NULL;
|
|
|
|
oldcu->id.us--; /* because new curve is a copy: reduce user count */
|
|
|
|
|
|
|
|
/* 2. put new object in editmode and clear it */
|
|
|
|
make_editNurb(newob);
|
|
|
|
newedit= newcu->editnurb;
|
2010-07-25 11:57:36 +00:00
|
|
|
freeNurblist(&newedit->nurbs);
|
|
|
|
free_editNurb_keyIndex(newedit);
|
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
|
|
|
|
|
|
|
/* 3. move over parts from old object */
|
2010-07-25 11:57:36 +00:00
|
|
|
for(nu= oldedit->nurbs.first; nu; nu=nu1) {
|
2009-01-14 12:26:45 +00:00
|
|
|
nu1= nu->next;
|
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
|
|
|
|
|
|
|
if(isNurbsel(nu)) {
|
2010-07-25 11:57:36 +00:00
|
|
|
BLI_remlink(&oldedit->nurbs, nu);
|
|
|
|
BLI_addtail(&newedit->nurbs, nu);
|
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
|
|
|
/* 4. put old object out of editmode */
|
|
|
|
load_editNurb(newob);
|
|
|
|
free_editNurb(newob);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-12-05 18:59:23 +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
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_DATA, oldob->data);
|
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 */
|
|
|
|
ot->name= "Separate";
|
|
|
|
ot->idname= "CURVE_OT_separate";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= separate_exec;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
}
|
2009-01-14 12:26:45 +00:00
|
|
|
|
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
|
|
|
{
|
|
|
|
/* return u!=-1: 1 row in u-direction selected. U has value between 0-pntsv
|
2010-03-22 09:30:00 +00:00
|
|
|
* return v!=-1: 1 collumn in v-direction selected. V has value between 0-pntsu
|
|
|
|
*/
|
2009-01-14 12:26:45 +00:00
|
|
|
BPoint *bp;
|
|
|
|
int a, b, sel;
|
|
|
|
|
|
|
|
*u= *v= -1;
|
|
|
|
|
|
|
|
bp= nu->bp;
|
|
|
|
for(b=0; b<nu->pntsv; b++) {
|
|
|
|
sel= 0;
|
|
|
|
for(a=0; a<nu->pntsu; a++, bp++) {
|
|
|
|
if(bp->f1 & flag) sel++;
|
|
|
|
}
|
|
|
|
if(sel==nu->pntsu) {
|
|
|
|
if(*u== -1) *u= b;
|
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
else if(sel>1) return 0; /* because sel==1 is still ok */
|
|
|
|
}
|
|
|
|
|
|
|
|
for(a=0; a<nu->pntsu; a++) {
|
|
|
|
sel= 0;
|
|
|
|
bp= nu->bp+a;
|
|
|
|
for(b=0; b<nu->pntsv; b++, bp+=nu->pntsu) {
|
|
|
|
if(bp->f1 & flag) sel++;
|
|
|
|
}
|
|
|
|
if(sel==nu->pntsv) {
|
|
|
|
if(*v== -1) *v= a;
|
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
else if(sel>1) return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(*u==-1 && *v>-1) return 1;
|
|
|
|
if(*v==-1 && *u>-1) return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
static void setflagsNurb(ListBase *editnurb, short flag)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu->pntsu;
|
|
|
|
bezt= nu->bezt;
|
|
|
|
while(a--) {
|
|
|
|
bezt->f1= bezt->f2= bezt->f3= flag;
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a--) {
|
|
|
|
bp->f1= flag;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
static void rotateflagNurb(ListBase *editnurb, short flag, float *cent, float rotmat[][3])
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
|
|
|
/* all verts with (flag & 'flag') rotate */
|
|
|
|
Nurb *nu;
|
|
|
|
BPoint *bp;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_NURBS) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
|
|
|
|
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++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
static void translateflagNurb(ListBase *editnurb, short flag, float *vec)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
|
|
|
/* all verts with ('flag' & flag) translate */
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu->pntsu;
|
|
|
|
bezt= nu->bezt;
|
|
|
|
while(a--) {
|
2010-04-21 12:27:48 +00:00
|
|
|
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 {
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a--) {
|
2010-04-21 12:27:48 +00:00
|
|
|
if(bp->f1 & flag) add_v3_v3(bp->vec, vec);
|
2009-01-14 12:26:45 +00:00
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
test2DNurb(nu);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_NURBS) {
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
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 */
|
|
|
|
bp->vec[3]*= w;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int deleteflagNurb(bContext *C, wmOperator *UNUSED(op), int flag)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
Curve *cu= obedit->data;
|
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu, *next;
|
|
|
|
BPoint *bp, *bpn, *newbp;
|
|
|
|
int a, b, newu, newv, sel;
|
|
|
|
|
|
|
|
if(obedit && obedit->type==OB_SURF);
|
2009-02-11 23:02:21 +00:00
|
|
|
else return OPERATOR_CANCELLED;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-04-30 04:48:40 +00:00
|
|
|
cu->lastsel= NULL;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
nu= editnurb->first;
|
|
|
|
while(nu) {
|
|
|
|
next= nu->next;
|
|
|
|
|
|
|
|
/* is entire nurb selected */
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
while(a) {
|
|
|
|
a--;
|
|
|
|
if(bp->f1 & flag);
|
|
|
|
else break;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
if(a==0) {
|
|
|
|
BLI_remlink(editnurb, nu);
|
2010-07-25 11:57:36 +00:00
|
|
|
keyIndex_delNurb(cu->editnurb, nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
freeNurb(nu); nu=NULL;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* is nurb in U direction selected */
|
|
|
|
newv= nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
for(b=0; b<nu->pntsv; b++) {
|
|
|
|
sel= 0;
|
|
|
|
for(a=0; a<nu->pntsu; a++, bp++) {
|
|
|
|
if(bp->f1 & flag) sel++;
|
|
|
|
}
|
|
|
|
if(sel==nu->pntsu) {
|
|
|
|
newv--;
|
|
|
|
}
|
|
|
|
else if(sel>=1) {
|
|
|
|
/* don't delete */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(newv!=nu->pntsv && b==nu->pntsv) {
|
|
|
|
/* delete */
|
|
|
|
bp= nu->bp;
|
|
|
|
bpn = newbp =
|
|
|
|
(BPoint*) MEM_mallocN(newv * nu->pntsu * sizeof(BPoint), "deleteNurb");
|
|
|
|
for(b=0; b<nu->pntsv; b++) {
|
|
|
|
if((bp->f1 & flag)==0) {
|
|
|
|
memcpy(bpn, bp, nu->pntsu*sizeof(BPoint));
|
2010-12-06 21:18:08 +00:00
|
|
|
keyIndex_updateBP(cu->editnurb, bp, bpn, nu->pntsu);
|
2009-01-14 12:26:45 +00:00
|
|
|
bpn+= nu->pntsu;
|
2010-07-25 11:57:36 +00:00
|
|
|
} else {
|
|
|
|
keyIndex_delBP(cu->editnurb, bp);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
bp+= nu->pntsu;
|
|
|
|
}
|
|
|
|
nu->pntsv= newv;
|
|
|
|
MEM_freeN(nu->bp);
|
|
|
|
nu->bp= newbp;
|
|
|
|
clamp_nurb_order_v(nu);
|
|
|
|
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_v(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* is the nurb in V direction selected */
|
|
|
|
newu= nu->pntsu;
|
|
|
|
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) {
|
|
|
|
newu--;
|
|
|
|
}
|
|
|
|
else if(sel>=1) {
|
|
|
|
/* don't delete */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(newu!=nu->pntsu && a==nu->pntsu) {
|
|
|
|
/* delete */
|
|
|
|
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++) {
|
|
|
|
if((bp->f1 & flag)==0) {
|
|
|
|
*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++;
|
2010-07-25 11:57:36 +00:00
|
|
|
} else {
|
|
|
|
keyIndex_delBP(cu->editnurb, bp);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MEM_freeN(nu->bp);
|
|
|
|
nu->bp= newbp;
|
|
|
|
if(newu==1 && nu->pntsv>1) { /* make a U spline */
|
|
|
|
nu->pntsu= nu->pntsv;
|
|
|
|
nu->pntsv= 1;
|
|
|
|
SWAP(short, nu->orderu, nu->orderv);
|
|
|
|
clamp_nurb_order_u(nu);
|
|
|
|
if(nu->knotsv) MEM_freeN(nu->knotsv);
|
|
|
|
nu->knotsv= NULL;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
nu->pntsu= newu;
|
|
|
|
clamp_nurb_order_u(nu);
|
|
|
|
}
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nu= next;
|
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
|
2010-12-20 19:47:16 +00:00
|
|
|
if(ED_curve_updateAnimPaths(obedit))
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, obedit);
|
2010-12-06 17:20:22 +00:00
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* only for OB_SURF */
|
2010-07-25 11:57:36 +00:00
|
|
|
static short extrudeflagNurb(EditNurb *editnurb, int flag)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
|
|
|
Nurb *nu;
|
|
|
|
BPoint *bp, *bpn, *newbp;
|
|
|
|
int ok= 0, a, u, v, len;
|
|
|
|
|
2010-07-25 11:57:36 +00:00
|
|
|
nu= editnurb->nurbs.first;
|
2009-01-14 12:26:45 +00:00
|
|
|
while(nu) {
|
|
|
|
|
|
|
|
if(nu->pntsv==1) {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a) {
|
|
|
|
if(bp->f1 & flag);
|
|
|
|
else break;
|
|
|
|
bp++;
|
|
|
|
a--;
|
|
|
|
}
|
|
|
|
if(a==0) {
|
|
|
|
ok= 1;
|
|
|
|
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);
|
2009-01-14 12:26:45 +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);
|
|
|
|
nu->bp= newbp;
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a--) {
|
|
|
|
select_bpoint(bp, SELECT, flag, HIDDEN);
|
|
|
|
select_bpoint(newbp, DESELECT, flag, HIDDEN);
|
|
|
|
bp++;
|
|
|
|
newbp++;
|
|
|
|
}
|
|
|
|
|
|
|
|
nu->pntsv= 2;
|
|
|
|
nu->orderv= 2;
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_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
|
|
|
|
|
|
|
if( isNurbselUV(nu, &u, &v, flag) ) {
|
|
|
|
|
|
|
|
/* deselect all */
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
while(a--) {
|
|
|
|
select_bpoint(bp, DESELECT, flag, HIDDEN);
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(u==0 || u== nu->pntsv-1) { /* row in u-direction selected */
|
|
|
|
ok= 1;
|
|
|
|
newbp =
|
|
|
|
(BPoint*) MEM_mallocN(nu->pntsu*(nu->pntsv + 1)
|
|
|
|
* sizeof(BPoint), "extrudeNurb1");
|
|
|
|
if(u==0) {
|
|
|
|
len= nu->pntsv*nu->pntsu;
|
2010-07-25 11:57:36 +00:00
|
|
|
ED_curve_bpcpy(editnurb, newbp+nu->pntsu, nu->bp, len);
|
|
|
|
ED_curve_bpcpy(editnurb, newbp, nu->bp, nu->pntsu);
|
2009-01-14 12:26:45 +00:00
|
|
|
bp= newbp;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
len= nu->pntsv*nu->pntsu;
|
2010-07-25 11:57:36 +00:00
|
|
|
ED_curve_bpcpy(editnurb, newbp, nu->bp, len);
|
|
|
|
ED_curve_bpcpy(editnurb, newbp+len, nu->bp+len-nu->pntsu, nu->pntsu);
|
2009-01-14 12:26:45 +00:00
|
|
|
bp= newbp+len;
|
|
|
|
}
|
|
|
|
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a--) {
|
|
|
|
select_bpoint(bp, SELECT, flag, HIDDEN);
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
|
|
|
|
MEM_freeN(nu->bp);
|
|
|
|
nu->bp= newbp;
|
|
|
|
nu->pntsv++;
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_v(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
else if(v==0 || v== nu->pntsu-1) { /* collumn in v-direction selected */
|
|
|
|
ok= 1;
|
|
|
|
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;
|
|
|
|
bpn->f1 |= flag;
|
|
|
|
bpn++;
|
|
|
|
}
|
2010-07-25 11:57:36 +00:00
|
|
|
ED_curve_bpcpy(editnurb, bpn, bp, nu->pntsu);
|
2009-01-14 12:26:45 +00:00
|
|
|
bp+= nu->pntsu;
|
|
|
|
bpn+= nu->pntsu;
|
|
|
|
if(v== nu->pntsu-1) {
|
|
|
|
*bpn= *(bp-1);
|
|
|
|
bpn->f1 |= flag;
|
|
|
|
bpn++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MEM_freeN(nu->bp);
|
|
|
|
nu->bp= newbp;
|
|
|
|
nu->pntsu++;
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
static void adduplicateflagNurb(Object *obedit, short flag)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu, *newnu;
|
|
|
|
BezTriple *bezt, *bezt1;
|
|
|
|
BPoint *bp, *bp1;
|
2010-04-30 04:48:40 +00:00
|
|
|
Curve *cu= (Curve*)obedit->data;
|
2009-01-14 12:26:45 +00:00
|
|
|
int a, b, starta, enda, newu, newv;
|
|
|
|
char *usel;
|
|
|
|
|
2010-04-30 04:48:40 +00:00
|
|
|
cu->lastsel= NULL;
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
nu= editnurb->last;
|
|
|
|
while(nu) {
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt= nu->bezt;
|
|
|
|
for(a=0; a<nu->pntsu; a++) {
|
|
|
|
enda= -1;
|
|
|
|
starta= a;
|
|
|
|
while( (bezt->f1 & flag) || (bezt->f2 & flag) || (bezt->f3 & flag) ) {
|
|
|
|
select_beztriple(bezt, DESELECT, flag, HIDDEN);
|
|
|
|
enda=a;
|
|
|
|
if(a>=nu->pntsu-1) break;
|
|
|
|
a++;
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
if(enda>=starta) {
|
|
|
|
newnu = (Nurb*)MEM_mallocN(sizeof(Nurb), "adduplicateN");
|
|
|
|
memcpy(newnu, nu, sizeof(Nurb));
|
|
|
|
BLI_addtail(editnurb, newnu);
|
|
|
|
set_actNurb(obedit, newnu);
|
|
|
|
newnu->pntsu= enda-starta+1;
|
|
|
|
newnu->bezt=
|
|
|
|
(BezTriple*)MEM_mallocN((enda - starta + 1) * sizeof(BezTriple), "adduplicateN");
|
|
|
|
memcpy(newnu->bezt, nu->bezt+starta, newnu->pntsu*sizeof(BezTriple));
|
|
|
|
|
|
|
|
b= newnu->pntsu;
|
|
|
|
bezt1= newnu->bezt;
|
|
|
|
while(b--) {
|
|
|
|
select_beztriple(bezt1, SELECT, flag, HIDDEN);
|
|
|
|
bezt1++;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
if(nu->flagu & CU_NURB_CYCLIC) {
|
2009-01-14 12:26:45 +00:00
|
|
|
if(starta!=0 || enda!=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
|
|
|
newnu->flagu &= ~CU_NURB_CYCLIC;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(nu->pntsv==1) { /* because UV Nurb has a different method for dupli */
|
|
|
|
bp= nu->bp;
|
|
|
|
for(a=0; a<nu->pntsu; a++) {
|
|
|
|
enda= -1;
|
|
|
|
starta= a;
|
|
|
|
while(bp->f1 & flag) {
|
|
|
|
select_bpoint(bp, DESELECT, flag, HIDDEN);
|
|
|
|
enda= a;
|
|
|
|
if(a>=nu->pntsu-1) break;
|
|
|
|
a++;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
if(enda>=starta) {
|
|
|
|
newnu = (Nurb*)MEM_mallocN(sizeof(Nurb), "adduplicateN3");
|
|
|
|
memcpy(newnu, nu, sizeof(Nurb));
|
|
|
|
set_actNurb(obedit, newnu);
|
|
|
|
BLI_addtail(editnurb, newnu);
|
|
|
|
newnu->pntsu= enda-starta+1;
|
|
|
|
newnu->bp = (BPoint*)MEM_mallocN((enda-starta+1) * sizeof(BPoint), "adduplicateN4");
|
|
|
|
memcpy(newnu->bp, nu->bp+starta, newnu->pntsu*sizeof(BPoint));
|
|
|
|
|
|
|
|
b= newnu->pntsu;
|
|
|
|
bp1= newnu->bp;
|
|
|
|
while(b--) {
|
|
|
|
select_bpoint(bp1, SELECT, flag, HIDDEN);
|
|
|
|
bp1++;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
if(nu->flagu & CU_NURB_CYCLIC) {
|
2009-01-14 12:26:45 +00:00
|
|
|
if(starta!=0 || enda!=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
|
|
|
newnu->flagu &= ~CU_NURB_CYCLIC;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* knots */
|
|
|
|
newnu->knotsu= NULL;
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(newnu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* a rectangular area in nurb has to be selected */
|
|
|
|
if(isNurbsel(nu)) {
|
|
|
|
usel= MEM_callocN(nu->pntsu, "adduplicateN4");
|
|
|
|
bp= nu->bp;
|
|
|
|
for(a=0; a<nu->pntsv; a++) {
|
|
|
|
for(b=0; b<nu->pntsu; b++, bp++) {
|
|
|
|
if(bp->f1 & flag) usel[b]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
newu= 0;
|
|
|
|
newv= 0;
|
|
|
|
for(a=0; a<nu->pntsu; a++) {
|
|
|
|
if(usel[a]) {
|
|
|
|
if(newv==0 || usel[a]==newv) {
|
|
|
|
newv= usel[a];
|
|
|
|
newu++;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
newv= 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(newu==0 || newv==0) {
|
2010-01-22 06:48:29 +00:00
|
|
|
if (G.f & G_DEBUG)
|
|
|
|
printf("Can't duplicate Nurb\n");
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
if(newu==1) SWAP(short, newu, newv);
|
|
|
|
|
|
|
|
newnu = (Nurb*)MEM_mallocN(sizeof(Nurb), "adduplicateN5");
|
|
|
|
memcpy(newnu, nu, sizeof(Nurb));
|
|
|
|
BLI_addtail(editnurb, newnu);
|
|
|
|
set_actNurb(obedit, newnu);
|
|
|
|
newnu->pntsu= newu;
|
|
|
|
newnu->pntsv= newv;
|
|
|
|
newnu->bp =
|
|
|
|
(BPoint*)MEM_mallocN(newu * newv * sizeof(BPoint), "adduplicateN6");
|
|
|
|
clamp_nurb_order_u(newnu);
|
|
|
|
clamp_nurb_order_v(newnu);
|
|
|
|
|
|
|
|
newnu->knotsu= newnu->knotsv= NULL;
|
|
|
|
|
|
|
|
bp= newnu->bp;
|
|
|
|
bp1= nu->bp;
|
|
|
|
for(a=0; a<nu->pntsv; a++) {
|
|
|
|
for(b=0; b<nu->pntsu; b++, bp1++) {
|
|
|
|
if(bp1->f1 & flag) {
|
|
|
|
memcpy(bp, bp1, sizeof(BPoint));
|
|
|
|
select_bpoint(bp1, DESELECT, flag, HIDDEN);
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (check_valid_nurb_u(newnu)) {
|
|
|
|
if(nu->pntsu==newnu->pntsu && nu->knotsu) {
|
|
|
|
newnu->knotsu= MEM_dupallocN( nu->knotsu );
|
|
|
|
} else {
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(newnu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (check_valid_nurb_v(newnu)) {
|
|
|
|
if(nu->pntsv==newnu->pntsv && nu->knotsv) {
|
|
|
|
newnu->knotsv= MEM_dupallocN( nu->knotsv );
|
|
|
|
} else {
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_v(newnu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MEM_freeN(usel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nu= nu->prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* actnu changed */
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2010-07-25 11:57:36 +00:00
|
|
|
Curve *cu= (Curve*)obedit->data;
|
|
|
|
EditNurb *editnurb= cu->editnurb;
|
2009-01-14 12:26:45 +00:00
|
|
|
Nurb *nu;
|
2010-07-25 11:57:36 +00:00
|
|
|
|
|
|
|
for(nu= editnurb->nurbs.first; nu; nu= nu->next)
|
|
|
|
if(isNurbsel(nu)) {
|
2009-02-11 23:02:21 +00:00
|
|
|
switchdirectionNurb(nu);
|
2010-07-25 11:57:36 +00:00
|
|
|
keyData_switchDirectionNurb(cu, nu);
|
|
|
|
}
|
|
|
|
|
2010-12-20 19:47:16 +00:00
|
|
|
if(ED_curve_updateAnimPaths(obedit))
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, obedit);
|
|
|
|
|
2011-01-03 12:41:16 +00:00
|
|
|
DAG_id_tag_update(obedit->data, 0);
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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 */
|
|
|
|
ot->name= "Switch Direction";
|
2010-12-18 09:18:39 +00:00
|
|
|
ot->description= "Switch direction of selected splines";
|
2009-02-11 23:02:21 +00:00
|
|
|
ot->idname= "CURVE_OT_switch_direction";
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= switch_direction_exec;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/* flags */
|
|
|
|
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-02 10:56:50 +00:00
|
|
|
static int set_goal_weight_exec(bContext *C, wmOperator *op)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
2009-02-11 23:02:21 +00:00
|
|
|
float weight= RNA_float_get(op->ptr, "weight");
|
2009-01-14 12:26:45 +00:00
|
|
|
int a;
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
if(nu->bezt) {
|
|
|
|
for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) {
|
|
|
|
if(bezt->f2 & SELECT)
|
|
|
|
bezt->weight= weight;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
}
|
|
|
|
else if(nu->bp) {
|
|
|
|
for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
|
|
|
|
if(bp->f1 & SELECT)
|
|
|
|
bp->weight= weight;
|
2009-01-14 12:26:45 +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);
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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 */
|
2010-12-18 09:18:39 +00:00
|
|
|
ot->name= "Set Goal Weight";
|
|
|
|
ot->description= "Set softbody goal weight for selected points";
|
2009-03-29 02:15:13 +00:00
|
|
|
ot->idname= "CURVE_OT_spline_weight_set";
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
2010-09-02 10:56:50 +00:00
|
|
|
ot->exec= set_goal_weight_exec;
|
2009-07-08 15:34:41 +00:00
|
|
|
ot->invoke= WM_operator_props_popup;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
/* properties */
|
2010-09-02 10:56:50 +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)
|
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
2009-02-11 23:02:21 +00:00
|
|
|
float radius= RNA_float_get(op->ptr, "radius");
|
2009-01-14 12:26:45 +00:00
|
|
|
int a;
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
if(nu->bezt) {
|
|
|
|
for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) {
|
|
|
|
if(bezt->f2 & SELECT)
|
|
|
|
bezt->radius= radius;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
}
|
|
|
|
else if(nu->bp) {
|
|
|
|
for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
|
|
|
|
if(bp->f1 & SELECT)
|
|
|
|
bp->radius= radius;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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 */
|
|
|
|
ot->name= "Set Curve Radius";
|
2010-12-18 09:18:39 +00:00
|
|
|
ot->description= "Set per-point radius which is used for bevel tapering";
|
2009-03-29 02:15:13 +00:00
|
|
|
ot->idname= "CURVE_OT_radius_set";
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= set_radius_exec;
|
2009-07-08 15:34:41 +00:00
|
|
|
ot->invoke= WM_operator_props_popup;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
/* properties */
|
|
|
|
RNA_def_float(ot->srna, "radius", 1.0f, 0.0f, FLT_MAX, "Radius", "", 0.0001f, 10.0f);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/********************* smooth operator ********************/
|
|
|
|
|
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
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt, *beztOrig;
|
|
|
|
BPoint *bp, *bpOrig;
|
|
|
|
float val, newval, offset;
|
2009-02-11 23:02:21 +00:00
|
|
|
int a, i, change = 0;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
if(nu->bezt) {
|
|
|
|
change = 0;
|
|
|
|
beztOrig = MEM_dupallocN( nu->bezt );
|
|
|
|
for(bezt=nu->bezt+1, a=1; a<nu->pntsu-1; a++, bezt++) {
|
|
|
|
if(bezt->f2 & SELECT) {
|
|
|
|
for(i=0; i<3; i++) {
|
|
|
|
val = bezt->vec[1][i];
|
|
|
|
newval = ((beztOrig+(a-1))->vec[1][i] * 0.5) + ((beztOrig+(a+1))->vec[1][i] * 0.5);
|
|
|
|
offset = (val*((1.0/6.0)*5)) + (newval*(1.0/6.0)) - val;
|
|
|
|
/* offset handles */
|
|
|
|
bezt->vec[1][i] += offset;
|
|
|
|
bezt->vec[0][i] += offset;
|
|
|
|
bezt->vec[2][i] += offset;
|
|
|
|
}
|
|
|
|
change = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MEM_freeN(beztOrig);
|
|
|
|
if (change)
|
|
|
|
calchandlesNurb(nu);
|
|
|
|
} else if (nu->bp) {
|
|
|
|
bpOrig = MEM_dupallocN( nu->bp );
|
|
|
|
/* Same as above, keep these the same! */
|
|
|
|
for(bp=nu->bp+1, a=1; a<nu->pntsu-1; a++, bp++) {
|
|
|
|
if(bp->f1 & SELECT) {
|
|
|
|
for(i=0; i<3; i++) {
|
|
|
|
val = bp->vec[i];
|
|
|
|
newval = ((bpOrig+(a-1))->vec[i] * 0.5) + ((bpOrig+(a+1))->vec[i] * 0.5);
|
|
|
|
offset = (val*((1.0/6.0)*5)) + (newval*(1.0/6.0)) - val;
|
|
|
|
|
|
|
|
bp->vec[i] += offset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MEM_freeN(bpOrig);
|
|
|
|
}
|
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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 */
|
|
|
|
ot->name= "Smooth";
|
2010-12-18 09:18:39 +00:00
|
|
|
ot->description= "Flatten angles of selected points";
|
2009-02-11 23:02:21 +00:00
|
|
|
ot->idname= "CURVE_OT_smooth";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= smooth_exec;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/**************** smooth curve radius operator *************/
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
/* TODO, make smoothing distance based */
|
2010-10-15 01:36:14 +00:00
|
|
|
static int smooth_radius_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
if(nu->bezt) {
|
|
|
|
|
|
|
|
for (last_sel=0; last_sel < nu->pntsu; last_sel++) {
|
|
|
|
/* loop over selection segments of a curve, smooth each */
|
|
|
|
|
|
|
|
/* 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;
|
2009-01-14 12:26:45 +00:00
|
|
|
for(bezt=nu->bezt+last_sel, a=last_sel; a<nu->pntsu; a++, bezt++) {
|
|
|
|
if(bezt->f2 & SELECT) {
|
|
|
|
start_sel = a;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* incase there are no other selected verts */
|
|
|
|
end_sel = start_sel;
|
|
|
|
for(bezt=nu->bezt+(start_sel+1), a=start_sel+1; a<nu->pntsu; a++, bezt++) {
|
|
|
|
if((bezt->f2 & SELECT)==0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
end_sel = a;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (start_sel == -1) {
|
|
|
|
last_sel = nu->pntsu; /* next... */
|
|
|
|
} else {
|
|
|
|
last_sel = end_sel; /* before we modify it */
|
|
|
|
|
|
|
|
/* now blend between start and end sel */
|
|
|
|
start_rad = end_rad = -1.0;
|
|
|
|
|
|
|
|
if (start_sel == end_sel) {
|
|
|
|
/* simple, only 1 point selected */
|
|
|
|
if (start_sel>0) start_rad = (nu->bezt+start_sel-1)->radius;
|
|
|
|
if (end_sel!=-1 && end_sel < nu->pntsu) end_rad = (nu->bezt+start_sel+1)->radius;
|
|
|
|
|
|
|
|
if (start_rad >= 0.0 && end_rad >= 0.0) (nu->bezt+start_sel)->radius = (start_rad + end_rad)/2;
|
|
|
|
else if (start_rad >= 0.0) (nu->bezt+start_sel)->radius = start_rad;
|
|
|
|
else if (end_rad >= 0.0) (nu->bezt+start_sel)->radius = end_rad;
|
|
|
|
} else {
|
|
|
|
/* if endpoints selected, then use them */
|
|
|
|
if (start_sel==0) {
|
|
|
|
start_rad = (nu->bezt+start_sel)->radius;
|
|
|
|
start_sel++; /* we dont want to edit the selected endpoint */
|
|
|
|
} else {
|
|
|
|
start_rad = (nu->bezt+start_sel-1)->radius;
|
|
|
|
}
|
|
|
|
if (end_sel==nu->pntsu-1) {
|
|
|
|
end_rad = (nu->bezt+end_sel)->radius;
|
|
|
|
end_sel--; /* we dont want to edit the selected endpoint */
|
|
|
|
} else {
|
|
|
|
end_rad = (nu->bezt+end_sel+1)->radius;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now Blend between the points */
|
|
|
|
range = (float)(end_sel - start_sel) + 2.0f;
|
|
|
|
for(bezt=nu->bezt+start_sel, a=start_sel; a<=end_sel; a++, bezt++) {
|
|
|
|
fac = (float)(1+a-start_sel) / range;
|
|
|
|
bezt->radius = start_rad*(1.0-fac) + end_rad*fac;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (nu->bp) {
|
|
|
|
/* Same as above, keep these the same! */
|
|
|
|
for (last_sel=0; last_sel < nu->pntsu; last_sel++) {
|
|
|
|
/* loop over selection segments of a curve, smooth each */
|
|
|
|
|
|
|
|
/* 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;
|
2009-01-14 12:26:45 +00:00
|
|
|
for(bp=nu->bp+last_sel, a=last_sel; a<nu->pntsu; a++, bp++) {
|
|
|
|
if(bp->f1 & SELECT) {
|
|
|
|
start_sel = a;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* incase there are no other selected verts */
|
|
|
|
end_sel = start_sel;
|
|
|
|
for(bp=nu->bp+(start_sel+1), a=start_sel+1; a<nu->pntsu; a++, bp++) {
|
|
|
|
if((bp->f1 & SELECT)==0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
end_sel = a;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (start_sel == -1) {
|
|
|
|
last_sel = nu->pntsu; /* next... */
|
|
|
|
} else {
|
|
|
|
last_sel = end_sel; /* before we modify it */
|
|
|
|
|
|
|
|
/* now blend between start and end sel */
|
|
|
|
start_rad = end_rad = -1.0;
|
|
|
|
|
|
|
|
if (start_sel == end_sel) {
|
|
|
|
/* simple, only 1 point selected */
|
|
|
|
if (start_sel>0) start_rad = (nu->bp+start_sel-1)->radius;
|
|
|
|
if (end_sel!=-1 && end_sel < nu->pntsu) end_rad = (nu->bp+start_sel+1)->radius;
|
|
|
|
|
|
|
|
if (start_rad >= 0.0 && end_rad >= 0.0) (nu->bp+start_sel)->radius = (start_rad + end_rad)/2;
|
|
|
|
else if (start_rad >= 0.0) (nu->bp+start_sel)->radius = start_rad;
|
|
|
|
else if (end_rad >= 0.0) (nu->bp+start_sel)->radius = end_rad;
|
|
|
|
} else {
|
|
|
|
/* if endpoints selected, then use them */
|
|
|
|
if (start_sel==0) {
|
|
|
|
start_rad = (nu->bp+start_sel)->radius;
|
|
|
|
start_sel++; /* we dont want to edit the selected endpoint */
|
|
|
|
} else {
|
|
|
|
start_rad = (nu->bp+start_sel-1)->radius;
|
|
|
|
}
|
|
|
|
if (end_sel==nu->pntsu-1) {
|
|
|
|
end_rad = (nu->bp+end_sel)->radius;
|
|
|
|
end_sel--; /* we dont want to edit the selected endpoint */
|
|
|
|
} else {
|
|
|
|
end_rad = (nu->bp+end_sel+1)->radius;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now Blend between the points */
|
|
|
|
range = (float)(end_sel - start_sel) + 2.0f;
|
|
|
|
for(bp=nu->bp+start_sel, a=start_sel; a<=end_sel; a++, bp++) {
|
|
|
|
fac = (float)(1+a-start_sel) / range;
|
|
|
|
bp->radius = start_rad*(1.0-fac) + end_rad*fac;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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 */
|
|
|
|
ot->name= "Smooth Curve Radius";
|
2010-12-18 09:18:39 +00:00
|
|
|
ot->description= "Flatten radiuses of selected points";
|
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
|
|
|
ot->idname= "CURVE_OT_smooth_radius";
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* api clastbacks */
|
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
|
|
|
ot->exec= smooth_radius_exec;
|
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
}
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/***************** selection utility *************************/
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
/* next == 1 -> select next */
|
|
|
|
/* next == -1 -> select previous */
|
|
|
|
/* cont == 1 -> select continuously */
|
|
|
|
/* selstatus, inverts behaviour */
|
|
|
|
static void select_adjacent_cp(ListBase *editnurb, short next, short cont, short selstatus)
|
|
|
|
{
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
|
|
|
int a;
|
|
|
|
short lastsel= 0, sel=0;
|
|
|
|
|
|
|
|
if(next==0) return;
|
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
lastsel=0;
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu->pntsu;
|
|
|
|
bezt= nu->bezt;
|
|
|
|
if(next < 0) bezt= (nu->bezt + (a-1));
|
|
|
|
while(a--) {
|
|
|
|
if(a-abs(next) < 0) break;
|
|
|
|
sel= 0;
|
|
|
|
if((lastsel==0) && (bezt->hide==0) && ((bezt->f2 & SELECT) || (selstatus==0))) {
|
|
|
|
bezt+=next;
|
|
|
|
if(!(bezt->f2 & SELECT) || (selstatus==0)) {
|
|
|
|
sel= select_beztriple(bezt, selstatus, 1, VISIBLE);
|
|
|
|
if((sel==1) && (cont==0)) lastsel= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bezt+=next;
|
|
|
|
lastsel= 0;
|
|
|
|
}
|
|
|
|
/* move around in zigzag way so that we go through each */
|
|
|
|
bezt-=(next-next/abs(next));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
if(next < 0) bp= (nu->bp + (a-1));
|
|
|
|
while(a--) {
|
|
|
|
if(a-abs(next) < 0) break;
|
|
|
|
sel=0;
|
|
|
|
if((lastsel==0) && (bp->hide==0) && ((bp->f1 & SELECT) || (selstatus==0))) {
|
|
|
|
bp+=next;
|
|
|
|
if(!(bp->f1 & SELECT) || (selstatus==0)) {
|
|
|
|
sel= select_bpoint(bp, selstatus, 1, VISIBLE);
|
|
|
|
if((sel==1) && (cont==0)) lastsel= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp+=next;
|
|
|
|
lastsel= 0;
|
|
|
|
}
|
|
|
|
/* move around in zigzag way so that we go through each */
|
|
|
|
bp-=(next-next/abs(next));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/**************** select start/end operators **************/
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
/* (de)selects first or last of visible part of each Nurb depending on selFirst */
|
|
|
|
/* selFirst: defines the end of which to select */
|
|
|
|
/* doswap: defines if selection state of each first/last control point is swapped */
|
|
|
|
/* selstatus: selection status in case doswap is false */
|
2009-02-11 23:02:21 +00:00
|
|
|
void selectend_nurb(Object *obedit, short selfirst, short doswap, short selstatus)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
|
|
|
BPoint *bp;
|
|
|
|
BezTriple *bezt;
|
2010-04-30 04:48:40 +00:00
|
|
|
Curve *cu;
|
2009-01-14 12:26:45 +00:00
|
|
|
int a;
|
|
|
|
short sel;
|
2010-04-30 04:48:40 +00:00
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
if(obedit==0) return;
|
2010-04-30 04:48:40 +00:00
|
|
|
|
|
|
|
cu= (Curve*)obedit->data;
|
|
|
|
cu->lastsel= NULL;
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
sel= 0;
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu->pntsu;
|
|
|
|
|
|
|
|
/* which point? */
|
|
|
|
if(selfirst==0) { /* select last */
|
|
|
|
bezt= (nu->bezt + (a-1));
|
|
|
|
}
|
|
|
|
else { /* select first */
|
|
|
|
bezt= nu->bezt;
|
|
|
|
}
|
|
|
|
|
|
|
|
while(a--) {
|
|
|
|
if(doswap) sel= swap_selection_beztriple(bezt);
|
|
|
|
else sel= select_beztriple(bezt, selstatus, 1, VISIBLE);
|
|
|
|
|
|
|
|
if(sel==1) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
|
|
|
|
/* which point? */
|
|
|
|
if(selfirst==0) { /* select last */
|
|
|
|
bp= (nu->bp + (a-1));
|
|
|
|
}
|
|
|
|
else{ /* select first */
|
|
|
|
bp= nu->bp;
|
|
|
|
}
|
|
|
|
|
|
|
|
while(a--) {
|
|
|
|
if (bp->hide == 0) {
|
|
|
|
if(doswap) sel= swap_selection_bpoint(bp);
|
|
|
|
else sel= select_bpoint(bp, selstatus, 1, VISIBLE);
|
|
|
|
|
|
|
|
if(sel==1) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
}
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int de_select_first_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-02-11 23:02:21 +00:00
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
|
|
|
|
|
|
|
selectend_nurb(obedit, FIRST, 1, DESELECT);
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, 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_de_select_first(wmOperatorType *ot)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Select or Deselect First";
|
|
|
|
ot->idname= "CURVE_OT_de_select_first";
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/* api cfirstbacks */
|
|
|
|
ot->exec= de_select_first_exec;
|
|
|
|
ot->poll= ED_operator_editcurve;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
}
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int de_select_last_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-02-11 23:02:21 +00:00
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
|
|
|
|
|
|
|
selectend_nurb(obedit, LAST, 1, DESELECT);
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CURVE_OT_de_select_last(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Select or Deselect Last";
|
|
|
|
ot->idname= "CURVE_OT_de_select_last";
|
|
|
|
|
|
|
|
/* api clastbacks */
|
|
|
|
ot->exec= de_select_last_exec;
|
|
|
|
ot->poll= ED_operator_editcurve;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************* de select all operator ***************/
|
|
|
|
|
|
|
|
static short nurb_has_selected_cps(ListBase *editnurb)
|
|
|
|
{
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
|
|
|
int a;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-02-11 23:02:21 +00:00
|
|
|
a= nu->pntsu;
|
|
|
|
bezt= nu->bezt;
|
|
|
|
while(a--) {
|
|
|
|
if(bezt->hide==0) {
|
|
|
|
if((bezt->f1 & SELECT)
|
|
|
|
|| (bezt->f2 & SELECT)
|
|
|
|
|| (bezt->f3 & SELECT)) return 1;
|
|
|
|
}
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a--) {
|
|
|
|
if((bp->hide==0) && (bp->f1 & SELECT)) return 1;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int de_select_all_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
2009-11-29 22:16:29 +00:00
|
|
|
int action = RNA_enum_get(op->ptr, "action");
|
2009-11-30 12:50:22 +00:00
|
|
|
|
2009-11-29 22:16:29 +00:00
|
|
|
if (action == SEL_TOGGLE) {
|
|
|
|
action = SEL_SELECT;
|
|
|
|
if(nurb_has_selected_cps(editnurb))
|
|
|
|
action = SEL_DESELECT;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (action) {
|
|
|
|
case SEL_SELECT:
|
|
|
|
CU_select_all(obedit);
|
|
|
|
break;
|
|
|
|
case SEL_DESELECT:
|
|
|
|
CU_deselect_all(obedit);
|
|
|
|
break;
|
|
|
|
case SEL_INVERT:
|
2009-11-30 12:50:22 +00:00
|
|
|
CU_select_swap(obedit);
|
2009-11-29 22:16:29 +00:00
|
|
|
break;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-29 22:16:29 +00:00
|
|
|
void CURVE_OT_select_all(wmOperatorType *ot)
|
2009-02-11 23:02:21 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Select or Deselect All";
|
2009-11-29 22:16:29 +00:00
|
|
|
ot->idname= "CURVE_OT_select_all";
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= de_select_all_exec;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-11-30 12:50:22 +00:00
|
|
|
|
|
|
|
/* properties */
|
|
|
|
WM_operator_properties_select_all(ot);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-09-08 07:35:07 +00:00
|
|
|
Curve *cu= obedit->data;
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
|
|
|
BPoint *bp;
|
|
|
|
BezTriple *bezt;
|
2009-02-20 20:39:27 +00:00
|
|
|
int a, sel, invert= RNA_boolean_get(op->ptr, "unselected");
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
sel= 0;
|
|
|
|
while(a--) {
|
2009-09-08 07:35:07 +00:00
|
|
|
if(invert == 0 && BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
|
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
|
|
|
select_beztriple(bezt, DESELECT, 1, HIDDEN);
|
|
|
|
bezt->hide= 1;
|
|
|
|
}
|
2009-09-08 07:35:07 +00:00
|
|
|
else if(invert && !BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
|
2009-01-14 12:26:45 +00:00
|
|
|
select_beztriple(bezt, DESELECT, 1, HIDDEN);
|
|
|
|
bezt->hide= 1;
|
|
|
|
}
|
|
|
|
if(bezt->hide) sel++;
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
if(sel==nu->pntsu) nu->hide= 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
sel= 0;
|
|
|
|
while(a--) {
|
2009-02-11 23:02:21 +00:00
|
|
|
if(invert==0 && (bp->f1 & SELECT)) {
|
2009-01-14 12:26:45 +00:00
|
|
|
select_bpoint(bp, DESELECT, 1, HIDDEN);
|
|
|
|
bp->hide= 1;
|
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
else if(invert && (bp->f1 & SELECT)==0) {
|
2009-01-14 12:26:45 +00:00
|
|
|
select_bpoint(bp, DESELECT, 1, HIDDEN);
|
|
|
|
bp->hide= 1;
|
|
|
|
}
|
|
|
|
if(bp->hide) sel++;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
if(sel==nu->pntsu*nu->pntsv) nu->hide= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-03 12:41:16 +00:00
|
|
|
DAG_id_tag_update(obedit->data, 0);
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CURVE_OT_hide(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
2009-02-20 20:39:27 +00:00
|
|
|
ot->name= "Hide Selected";
|
2009-02-11 23:02:21 +00:00
|
|
|
ot->idname= "CURVE_OT_hide";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= hide_exec;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
/* props */
|
2009-02-20 20:39:27 +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
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
|
|
|
BPoint *bp;
|
|
|
|
BezTriple *bezt;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
nu->hide= 0;
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a--) {
|
|
|
|
if(bezt->hide) {
|
|
|
|
select_beztriple(bezt, SELECT, 1, HIDDEN);
|
|
|
|
bezt->hide= 0;
|
|
|
|
}
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
while(a--) {
|
|
|
|
if(bp->hide) {
|
|
|
|
select_bpoint(bp, SELECT, 1, HIDDEN);
|
|
|
|
bp->hide= 0;
|
|
|
|
}
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-03 12:41:16 +00:00
|
|
|
DAG_id_tag_update(obedit->data, 0);
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
|
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_reveal(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Reveal Hidden";
|
|
|
|
ot->idname= "CURVE_OT_reveal";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= reveal_exec;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/********************** select invert operator *********************/
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int select_inverse_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-09-08 07:35:07 +00:00
|
|
|
Curve *cu= obedit->data;
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
|
|
|
BPoint *bp;
|
|
|
|
BezTriple *bezt;
|
|
|
|
int a;
|
|
|
|
|
2010-04-30 04:48:40 +00:00
|
|
|
cu->lastsel= NULL;
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a--) {
|
|
|
|
if(bezt->hide==0) {
|
|
|
|
bezt->f2 ^= SELECT; /* always do the center point */
|
2009-09-08 07:35:07 +00:00
|
|
|
if((cu->drawflag & CU_HIDE_HANDLES)==0) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt->f1 ^= SELECT;
|
|
|
|
bezt->f3 ^= SELECT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
while(a--) {
|
|
|
|
swap_selection_bpoint(bp);
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-07-08 21:31:28 +00:00
|
|
|
void CURVE_OT_select_inverse(wmOperatorType *ot)
|
2009-02-11 23:02:21 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
2009-07-08 21:31:28 +00:00
|
|
|
ot->name= "Select Inverse";
|
|
|
|
ot->idname= "CURVE_OT_select_inverse";
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
2009-07-08 21:31:28 +00:00
|
|
|
ot->exec= select_inverse_exec;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
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.
|
|
|
|
*
|
|
|
|
* @deffunc subdividenurb subdivideNurb(void)
|
|
|
|
* @return Nothing
|
|
|
|
* @param None
|
|
|
|
*/
|
2009-02-11 23:02:21 +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
|
|
|
{
|
2009-09-08 07:35:07 +00:00
|
|
|
Curve *cu= obedit->data;
|
2010-11-26 17:08:22 +00:00
|
|
|
EditNurb *editnurb= cu->editnurb;
|
2009-01-14 12:26:45 +00:00
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *prevbezt, *bezt, *beztnew, *beztn;
|
|
|
|
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
|
|
|
|
|
|
|
// printf("*** subdivideNurb: entering subdivide\n");
|
|
|
|
|
2010-11-26 17:08:22 +00:00
|
|
|
for(nu= editnurb->nurbs.first; nu; nu= nu->next) {
|
2009-01-14 12:26:45 +00:00
|
|
|
amount= 0;
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2010-03-22 09:30:00 +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 */
|
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
|
|
|
if(nu->flagu & CU_NURB_CYCLIC) {
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu->pntsu;
|
|
|
|
bezt= nu->bezt;
|
|
|
|
prevbezt= bezt+(a-1);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
a= nu->pntsu-1;
|
|
|
|
prevbezt= nu->bezt;
|
|
|
|
bezt= prevbezt+1;
|
|
|
|
}
|
|
|
|
while(a--) {
|
2010-03-23 22:09:23 +00:00
|
|
|
if( BEZSELECTED_HIDDENHANDLES(cu, prevbezt) && BEZSELECTED_HIDDENHANDLES(cu, bezt) ) amount+=number_cuts;
|
2009-01-14 12:26:45 +00:00
|
|
|
prevbezt= bezt;
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(amount) {
|
|
|
|
/* insert */
|
|
|
|
beztnew =
|
|
|
|
(BezTriple*)MEM_mallocN((amount + nu->pntsu) * sizeof(BezTriple), "subdivNurb");
|
|
|
|
beztn= beztnew;
|
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
|
|
|
if(nu->flagu & CU_NURB_CYCLIC) {
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu->pntsu;
|
|
|
|
bezt= nu->bezt;
|
|
|
|
prevbezt= bezt+(a-1);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
a= nu->pntsu-1;
|
|
|
|
prevbezt= nu->bezt;
|
|
|
|
bezt= prevbezt+1;
|
|
|
|
}
|
|
|
|
while(a--) {
|
|
|
|
memcpy(beztn, prevbezt, sizeof(BezTriple));
|
2010-12-06 21:18:08 +00:00
|
|
|
keyIndex_updateBezt(editnurb, prevbezt, beztn, 1);
|
2009-01-14 12:26:45 +00:00
|
|
|
beztn++;
|
|
|
|
|
2009-09-08 07:35:07 +00:00
|
|
|
if( BEZSELECTED_HIDDENHANDLES(cu, prevbezt) && BEZSELECTED_HIDDENHANDLES(cu, bezt) ) {
|
2010-03-23 22:09:23 +00:00
|
|
|
float prevvec[3][3];
|
|
|
|
|
2010-03-24 19:14:10 +00:00
|
|
|
memcpy(prevvec, prevbezt->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);
|
|
|
|
|
|
|
|
memcpy(beztn, bezt, sizeof(BezTriple));
|
|
|
|
|
|
|
|
/* midpoint subdividing */
|
2010-03-24 17:52:51 +00:00
|
|
|
interp_v3_v3v3(vec, prevvec[1], prevvec[2], factor);
|
|
|
|
interp_v3_v3v3(vec+3, prevvec[2], bezt->vec[0], factor);
|
|
|
|
interp_v3_v3v3(vec+6, bezt->vec[0], bezt->vec[1], factor);
|
2010-03-23 22:09:23 +00:00
|
|
|
|
2010-03-24 17:52:51 +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 */
|
|
|
|
VECCOPY((beztn-1)->vec[2], vec);
|
|
|
|
/* new point */
|
|
|
|
VECCOPY(beztn->vec[0], vec+9);
|
2010-03-24 17:52:51 +00:00
|
|
|
interp_v3_v3v3(beztn->vec[1], vec+9, vec+12, factor);
|
2010-03-23 22:09:23 +00:00
|
|
|
VECCOPY(beztn->vec[2], vec+12);
|
|
|
|
/* handle of next bezt */
|
2010-03-24 19:04:32 +00:00
|
|
|
if(a==0 && i == number_cuts - 1 && (nu->flagu & CU_NURB_CYCLIC)) {VECCOPY(beztnew->vec[0], vec+6);}
|
2010-03-23 22:09:23 +00:00
|
|
|
else {VECCOPY(bezt->vec[0], vec+6);}
|
|
|
|
|
|
|
|
beztn->radius = (prevbezt->radius + bezt->radius)/2;
|
|
|
|
beztn->weight = (prevbezt->weight + bezt->weight)/2;
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
prevbezt= bezt;
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
/* last point */
|
2010-11-26 17:08:22 +00:00
|
|
|
if((nu->flagu & CU_NURB_CYCLIC)==0) {
|
|
|
|
memcpy(beztn, prevbezt, sizeof(BezTriple));
|
2010-12-06 21:18:08 +00:00
|
|
|
keyIndex_updateBezt(editnurb, prevbezt, beztn, 1);
|
2010-11-26 17:08:22 +00:00
|
|
|
}
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
MEM_freeN(nu->bezt);
|
|
|
|
nu->bezt= beztnew;
|
|
|
|
nu->pntsu+= amount;
|
|
|
|
|
|
|
|
calchandlesNurb(nu);
|
|
|
|
}
|
2009-09-08 00:23:33 +00:00
|
|
|
} /* End of 'if(nu->type == CU_BEZIER)' */
|
2009-01-14 12:26:45 +00:00
|
|
|
else if (nu->pntsv==1) {
|
2010-03-22 09:30:00 +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 */
|
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
|
|
|
if(nu->flagu & CU_NURB_CYCLIC) {
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu->pntsu;
|
|
|
|
bp= nu->bp;
|
|
|
|
prevbp= bp+(a-1);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
a= nu->pntsu-1;
|
|
|
|
prevbp= nu->bp;
|
|
|
|
bp= prevbp+1;
|
|
|
|
}
|
|
|
|
while(a--) {
|
2010-03-23 22:09:23 +00:00
|
|
|
if( (bp->f1 & SELECT) && (prevbp->f1 & SELECT) ) amount+=number_cuts;
|
2009-01-14 12:26:45 +00:00
|
|
|
prevbp= bp;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(amount) {
|
|
|
|
/* insert */
|
|
|
|
bpnew =
|
|
|
|
(BPoint*)MEM_mallocN((amount + nu->pntsu) * sizeof(BPoint), "subdivNurb2");
|
|
|
|
bpn= bpnew;
|
|
|
|
|
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
|
|
|
if(nu->flagu & CU_NURB_CYCLIC) {
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu->pntsu;
|
|
|
|
bp= nu->bp;
|
|
|
|
prevbp= bp+(a-1);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
a= nu->pntsu-1;
|
|
|
|
prevbp= nu->bp;
|
|
|
|
bp= prevbp+1;
|
|
|
|
}
|
|
|
|
while(a--) {
|
|
|
|
memcpy(bpn, prevbp, sizeof(BPoint));
|
2010-12-06 21:18:08 +00:00
|
|
|
keyIndex_updateBP(editnurb, prevbp, bpn, 1);
|
2009-01-14 12:26:45 +00:00
|
|
|
bpn++;
|
|
|
|
|
|
|
|
if( (bp->f1 & SELECT) && (prevbp->f1 & SELECT) ) {
|
2010-03-22 09:30:00 +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);
|
|
|
|
|
|
|
|
memcpy(bpn, bp, sizeof(BPoint));
|
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
|
|
|
|
|
|
|
}
|
|
|
|
prevbp= bp;
|
|
|
|
bp++;
|
|
|
|
}
|
2010-11-26 17:08:22 +00:00
|
|
|
if((nu->flagu & CU_NURB_CYCLIC)==0) { /* last point */
|
|
|
|
memcpy(bpn, prevbp, sizeof(BPoint));
|
2010-12-06 21:18:08 +00:00
|
|
|
keyIndex_updateBP(editnurb, prevbp, bpn, 1);
|
2010-11-26 17:08:22 +00:00
|
|
|
}
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
MEM_freeN(nu->bp);
|
|
|
|
nu->bp= bpnew;
|
|
|
|
nu->pntsu+= amount;
|
|
|
|
|
2009-04-20 15:06:46 +00:00
|
|
|
if(nu->type & CU_NURBS) {
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} /* End of 'else if(nu->pntsv==1)' */
|
2009-09-08 00:23:33 +00:00
|
|
|
else if(nu->type == CU_NURBS) {
|
2010-03-22 09:30:00 +00:00
|
|
|
/* This is a very strange test ... */
|
|
|
|
/**
|
|
|
|
Subdivide NURB surfaces - nzc 30-5-'00 -
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-03-22 09:30:00 +00: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 opration. 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 */
|
|
|
|
usel= MEM_callocN(sizeof(int)*nu->pntsu, "subivideNurb3");
|
|
|
|
vsel= MEM_callocN(sizeof(int)*nu->pntsv, "subivideNurb3");
|
|
|
|
sel= 0;
|
|
|
|
|
2010-03-22 09:30:00 +00:00
|
|
|
/* Count the number of selected points. */
|
2009-01-14 12:26:45 +00:00
|
|
|
bp= nu->bp;
|
|
|
|
for(a=0; a<nu->pntsv; a++) {
|
|
|
|
for(b=0; b<nu->pntsu; b++) {
|
|
|
|
if(bp->f1 & SELECT) {
|
|
|
|
usel[b]++;
|
|
|
|
vsel[a]++;
|
|
|
|
sel++;
|
|
|
|
}
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( sel == (nu->pntsu*nu->pntsv) ) { /* subdivide entire nurb */
|
2010-03-22 09:30:00 +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 */
|
|
|
|
int countu= nu->pntsu + (nu->pntsu - 1) * number_cuts;
|
|
|
|
|
|
|
|
/* total count of nodes after subdivision */
|
|
|
|
int tot= ((number_cuts+1)*nu->pntsu-number_cuts)*((number_cuts+1)*nu->pntsv-number_cuts);
|
|
|
|
|
|
|
|
bpn=bpnew= MEM_mallocN( tot*sizeof(BPoint), "subdivideNurb4");
|
2009-01-14 12:26:45 +00:00
|
|
|
bp= nu->bp;
|
|
|
|
/* first subdivide rows */
|
|
|
|
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++;
|
|
|
|
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);
|
|
|
|
*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
|
|
|
}
|
|
|
|
}
|
2010-03-23 22:09:23 +00:00
|
|
|
bpn+= number_cuts * countu;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
/* now insert new */
|
2010-03-23 22:09:23 +00:00
|
|
|
bpn= bpnew+((number_cuts+1)*nu->pntsu - number_cuts);
|
|
|
|
bp= bpnew+(number_cuts+1)*((number_cuts+1)*nu->pntsu-number_cuts);
|
2009-01-14 12:26:45 +00:00
|
|
|
prevbp= bpnew;
|
|
|
|
for(a=1; a<nu->pntsv; a++) {
|
|
|
|
|
2010-03-23 22:09:23 +00:00
|
|
|
for(b=0; b<(number_cuts+1)*nu->pntsu-number_cuts; b++) {
|
|
|
|
BPoint *tmp= bpn;
|
|
|
|
for (i = 0; i < number_cuts; i++) {
|
|
|
|
factor = (float)(i + 1) / (number_cuts + 1);
|
|
|
|
*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
|
|
|
}
|
2010-03-23 22:09:23 +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);
|
|
|
|
nu->bp= bpnew;
|
2010-03-23 22:09:23 +00:00
|
|
|
nu->pntsu= (number_cuts+1)*nu->pntsu-number_cuts;
|
|
|
|
nu->pntsv= (number_cuts+1)*nu->pntsv-number_cuts;
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(nu);
|
|
|
|
nurbs_knot_calc_v(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
} /* End of 'if(sel== nu->pntsu*nu->pntsv)' (subdivide entire NURB) */
|
|
|
|
else {
|
|
|
|
/* subdivide in v direction? */
|
|
|
|
sel= 0;
|
|
|
|
for(a=0; a<nu->pntsv-1; a++) {
|
2010-03-23 22:09:23 +00:00
|
|
|
if(vsel[a]==nu->pntsu && vsel[a+1]==nu->pntsu) sel+=number_cuts;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(sel) { /* V ! */
|
|
|
|
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++;
|
|
|
|
}
|
|
|
|
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);
|
|
|
|
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;
|
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++;
|
|
|
|
|
|
|
|
prevbp++;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
bp-= nu->pntsu;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MEM_freeN(nu->bp);
|
|
|
|
nu->bp= bpnew;
|
|
|
|
nu->pntsv+= sel;
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_v(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* or in u direction? */
|
|
|
|
sel= 0;
|
|
|
|
for(a=0; a<nu->pntsu-1; a++) {
|
2010-03-23 22:09:23 +00:00
|
|
|
if(usel[a]==nu->pntsv && usel[a+1]==nu->pntsv) sel+=number_cuts;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(sel) { /* U ! */
|
2010-03-22 09:30:00 +00:00
|
|
|
/* Inserting U points is sort of 'default' Flat curves only get */
|
|
|
|
/* U points inserted in them. */
|
2009-01-14 12:26:45 +00:00
|
|
|
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++;
|
|
|
|
if( (b<nu->pntsu-1) && usel[b]==nu->pntsv && usel[b+1]==nu->pntsv ) {
|
2010-03-23 22:09:23 +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...
|
|
|
|
*/
|
|
|
|
for (i = 0; i < number_cuts; i++) {
|
|
|
|
factor = (float)(i + 1) / (number_cuts + 1);
|
2009-01-14 12:26:45 +00:00
|
|
|
prevbp= bp- 1;
|
|
|
|
*bpn= *prevbp;
|
2010-03-24 17:52:51 +00:00
|
|
|
interp_v4_v4v4(bpn->vec, prevbp->vec, bp->vec, factor);
|
2009-01-14 12:26:45 +00:00
|
|
|
bpn++;
|
2010-03-23 22:09:23 +00:00
|
|
|
}
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MEM_freeN(nu->bp);
|
|
|
|
nu->bp= bpnew;
|
|
|
|
nu->pntsu+= sel;
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(nu); /* shift knots
|
2010-03-22 09:30:00 +00:00
|
|
|
forward */
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MEM_freeN(usel);
|
|
|
|
MEM_freeN(vsel);
|
|
|
|
|
2009-09-08 00:23:33 +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)
|
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
|
|
|
int number_cuts= RNA_int_get(op->ptr, "number_cuts");
|
|
|
|
|
|
|
|
subdividenurb(obedit, number_cuts);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-12-20 19:47:16 +00:00
|
|
|
if(ED_curve_updateAnimPaths(obedit))
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, obedit);
|
2010-12-06 17:20:22 +00:00
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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
|
|
|
void CURVE_OT_subdivide(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Subdivide";
|
2010-12-18 09:18:39 +00:00
|
|
|
ot->description= "Subdivide selected segments";
|
2009-02-11 23:02:21 +00:00
|
|
|
ot->idname= "CURVE_OT_subdivide";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= subdivide_exec;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2010-03-23 22:09:23 +00:00
|
|
|
|
2010-12-05 07:08:14 +00:00
|
|
|
RNA_def_int(ot->srna, "number_cuts", 1, 1, INT_MAX, "Number of cuts", "", 1, 10);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/******************** find nearest ************************/
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
|
|
|
|
{
|
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
|
|
|
struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; int dist, hpoint, select, mval[2]; } *data = userData;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
short flag;
|
|
|
|
short temp;
|
|
|
|
|
|
|
|
if (bp) {
|
|
|
|
flag = bp->f1;
|
|
|
|
} else {
|
|
|
|
if (beztindex==0) {
|
|
|
|
flag = bezt->f1;
|
|
|
|
} else if (beztindex==1) {
|
|
|
|
flag = bezt->f2;
|
|
|
|
} else {
|
|
|
|
flag = bezt->f3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
|
|
|
|
if ((flag&1)==data->select) temp += 5;
|
|
|
|
if (bezt && beztindex==1) temp += 3; /* middle points get a small disadvantage */
|
|
|
|
|
|
|
|
if (temp<data->dist) {
|
|
|
|
data->dist = temp;
|
|
|
|
|
|
|
|
data->bp = bp;
|
|
|
|
data->bezt = bezt;
|
|
|
|
data->nurb = nu;
|
|
|
|
data->hpoint = bezt?beztindex: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
|
|
|
static short findnearestNurbvert(ViewContext *vc, short sel, int mval[2], Nurb **nurb, BezTriple **bezt, BPoint **bp)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
|
|
|
/* sel==1: selected gets a disadvantage */
|
|
|
|
/* in nurb and bezt or bp the nearest is written */
|
|
|
|
/* return 0 1 2: handlepunt */
|
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
|
|
|
struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; int dist, hpoint, select, mval[2]; } data = {0};
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
data.dist = 100;
|
|
|
|
data.hpoint = 0;
|
|
|
|
data.select = sel;
|
|
|
|
data.mval[0] = mval[0];
|
|
|
|
data.mval[1] = mval[1];
|
|
|
|
|
2009-10-11 20:32:25 +00:00
|
|
|
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
|
2009-01-14 12:26:45 +00:00
|
|
|
nurbs_foreachScreenVert(vc, findnearestNurbvert__doClosest, &data);
|
|
|
|
|
|
|
|
*nurb = data.nurb;
|
|
|
|
*bezt = data.bezt;
|
|
|
|
*bp = data.bp;
|
|
|
|
|
|
|
|
return data.hpoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void findselectedNurbvert(ListBase *editnurb, Nurb **nu, BezTriple **bezt, BPoint **bp)
|
|
|
|
{
|
|
|
|
/* 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 */
|
|
|
|
Nurb *nu1;
|
|
|
|
BezTriple *bezt1;
|
|
|
|
BPoint *bp1;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
*nu= 0;
|
|
|
|
*bezt= 0;
|
|
|
|
*bp= 0;
|
|
|
|
for(nu1= editnurb->first; nu1; nu1= nu1->next) {
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu1->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt1= nu1->bezt;
|
|
|
|
a= nu1->pntsu;
|
|
|
|
while(a--) {
|
|
|
|
if( (bezt1->f1 & SELECT) || (bezt1->f2 & SELECT) || (bezt1->f3 & SELECT) ) {
|
|
|
|
if(*nu!=0 && *nu!= nu1) {
|
|
|
|
*nu= 0;
|
|
|
|
*bp= 0;
|
|
|
|
*bezt= 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if(*bezt || *bp) {
|
|
|
|
*bp= 0;
|
|
|
|
*bezt= 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*bezt= bezt1;
|
|
|
|
*nu= nu1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bezt1++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp1= nu1->bp;
|
|
|
|
a= nu1->pntsu*nu1->pntsv;
|
|
|
|
while(a--) {
|
|
|
|
if( bp1->f1 & 1 ) {
|
|
|
|
if(*nu!=0 && *nu!= nu1) {
|
|
|
|
*bp= 0;
|
|
|
|
*bezt= 0;
|
|
|
|
*nu= 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if(*bezt || *bp) {
|
|
|
|
*bp= 0;
|
|
|
|
*bezt= 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*bp= bp1;
|
|
|
|
*nu= nu1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bp1++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/***************** set spline type operator *******************/
|
|
|
|
|
|
|
|
static int convertspline(short type, Nurb *nu)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
|
|
|
int a, c, nr;
|
|
|
|
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_POLY) {
|
2009-01-14 12:26:45 +00:00
|
|
|
if(type==CU_BEZIER) { /* to Bezier with vecthandles */
|
|
|
|
nr= nu->pntsu;
|
|
|
|
bezt =
|
|
|
|
(BezTriple*)MEM_callocN(nr * sizeof(BezTriple), "setsplinetype2");
|
|
|
|
nu->bezt= bezt;
|
|
|
|
a= nr;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a--) {
|
|
|
|
VECCOPY(bezt->vec[1], bp->vec);
|
|
|
|
bezt->f1=bezt->f2=bezt->f3= bp->f1;
|
|
|
|
bezt->h1= bezt->h2= HD_VECT;
|
|
|
|
bezt->weight= bp->weight;
|
|
|
|
bezt->radius= bp->radius;
|
|
|
|
bp++;
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
MEM_freeN(nu->bp);
|
|
|
|
nu->bp= 0;
|
|
|
|
nu->pntsu= nr;
|
2009-09-08 00:23:33 +00:00
|
|
|
nu->type = CU_BEZIER;
|
2009-01-14 12:26:45 +00:00
|
|
|
calchandlesNurb(nu);
|
|
|
|
}
|
|
|
|
else if(type==CU_NURBS) {
|
2009-09-08 00:23:33 +00:00
|
|
|
nu->type = CU_NURBS;
|
2009-01-14 12:26:45 +00:00
|
|
|
nu->orderu= 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->flagu &= CU_NURB_CYCLIC; /* disable all flags except for cyclic */
|
|
|
|
nu->flagu |= CU_NURB_BEZIER;
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a--) {
|
|
|
|
bp->vec[3]= 1.0;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-09-08 00:23:33 +00:00
|
|
|
else if(nu->type == CU_BEZIER) { /* Bezier */
|
2009-09-08 07:35:07 +00:00
|
|
|
if(type==CU_POLY || type==CU_NURBS) {
|
2009-01-14 12:26:45 +00:00
|
|
|
nr= 3*nu->pntsu;
|
|
|
|
nu->bp = MEM_callocN(nr * sizeof(BPoint), "setsplinetype");
|
|
|
|
a= nu->pntsu;
|
|
|
|
bezt= nu->bezt;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a--) {
|
2009-09-08 07:35:07 +00:00
|
|
|
if(type==CU_POLY && bezt->h1==HD_VECT && bezt->h2==HD_VECT) {
|
2009-01-14 12:26:45 +00:00
|
|
|
/* vector handle becomes 1 poly vertice */
|
|
|
|
VECCOPY(bp->vec, bezt->vec[1]);
|
|
|
|
bp->vec[3]= 1.0;
|
|
|
|
bp->f1= bezt->f2;
|
|
|
|
nr-= 2;
|
|
|
|
bp->radius= bezt->radius;
|
|
|
|
bp->weight= bezt->weight;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
for(c=0;c<3;c++) {
|
|
|
|
VECCOPY(bp->vec, bezt->vec[c]);
|
|
|
|
bp->vec[3]= 1.0;
|
|
|
|
if(c==0) bp->f1= bezt->f1;
|
|
|
|
else if(c==1) bp->f1= bezt->f2;
|
|
|
|
else bp->f1= bezt->f3;
|
|
|
|
bp->radius= bezt->radius;
|
|
|
|
bp->weight= bezt->weight;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
MEM_freeN(nu->bezt);
|
2009-09-08 07:35:07 +00:00
|
|
|
nu->bezt= NULL;
|
2009-01-14 12:26:45 +00:00
|
|
|
nu->pntsu= nr;
|
|
|
|
nu->pntsv= 1;
|
|
|
|
nu->orderu= 4;
|
|
|
|
nu->orderv= 1;
|
2009-09-08 07:35:07 +00:00
|
|
|
nu->type = type;
|
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
|
|
|
if(nu->flagu & CU_NURB_CYCLIC) c= nu->orderu-1;
|
2009-01-14 12:26:45 +00:00
|
|
|
else c= 0;
|
2009-09-08 07:35:07 +00:00
|
|
|
if(type== CU_NURBS) {
|
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; /* disable all flags except for cyclic */
|
|
|
|
nu->flagu |= CU_NURB_BEZIER;
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-09-08 00:23:33 +00:00
|
|
|
else if(nu->type == CU_NURBS) {
|
|
|
|
if(type==CU_POLY) {
|
|
|
|
nu->type = CU_POLY;
|
2009-01-14 12:26:45 +00:00
|
|
|
if(nu->knotsu) MEM_freeN(nu->knotsu); /* python created nurbs have a knotsu of zero */
|
|
|
|
nu->knotsu= NULL;
|
|
|
|
if(nu->knotsv) MEM_freeN(nu->knotsv);
|
|
|
|
nu->knotsv= NULL;
|
|
|
|
}
|
|
|
|
else if(type==CU_BEZIER) { /* to Bezier */
|
|
|
|
nr= nu->pntsu/3;
|
|
|
|
|
|
|
|
if(nr<2)
|
|
|
|
return 1; /* conversion impossible */
|
|
|
|
else {
|
|
|
|
bezt = MEM_callocN(nr * sizeof(BezTriple), "setsplinetype2");
|
|
|
|
nu->bezt= bezt;
|
|
|
|
a= nr;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a--) {
|
|
|
|
VECCOPY(bezt->vec[0], bp->vec);
|
|
|
|
bezt->f1= bp->f1;
|
|
|
|
bp++;
|
|
|
|
VECCOPY(bezt->vec[1], bp->vec);
|
|
|
|
bezt->f2= bp->f1;
|
|
|
|
bp++;
|
|
|
|
VECCOPY(bezt->vec[2], bp->vec);
|
|
|
|
bezt->f3= bp->f1;
|
|
|
|
bezt->radius= bp->radius;
|
|
|
|
bezt->weight= bp->weight;
|
|
|
|
bp++;
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
MEM_freeN(nu->bp);
|
|
|
|
nu->bp= 0;
|
|
|
|
MEM_freeN(nu->knotsu);
|
|
|
|
nu->knotsu= NULL;
|
|
|
|
nu->pntsu= nr;
|
2009-09-08 00:23:33 +00:00
|
|
|
nu->type = CU_BEZIER;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
static int set_spline_type_exec(bContext *C, wmOperator *op)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
2009-02-11 23:02:21 +00:00
|
|
|
int changed=0, type= RNA_enum_get(op->ptr, "type");
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
if(type==CU_CARDINAL || type==CU_BSPLINE) {
|
2009-02-11 23:02:21 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Not implemented yet");
|
|
|
|
return OPERATOR_CANCELLED;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
if(isNurbsel(nu)) {
|
2009-02-11 23:02:21 +00:00
|
|
|
if(convertspline(type, nu))
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "No conversion possible");
|
|
|
|
else
|
|
|
|
changed= 1;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
|
2009-09-08 07:35:07 +00:00
|
|
|
if(changed) {
|
2010-12-20 19:47:16 +00:00
|
|
|
if(ED_curve_updateAnimPaths(obedit))
|
|
|
|
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);
|
2009-09-08 07:35:07 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
|
|
|
|
|
|
|
|
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
|
|
|
{
|
|
|
|
static EnumPropertyItem type_items[]= {
|
2009-06-16 00:52:21 +00:00
|
|
|
{CU_POLY, "POLY", 0, "Poly", ""},
|
|
|
|
{CU_BEZIER, "BEZIER", 0, "Bezier", ""},
|
2009-09-08 07:35:07 +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", ""},
|
|
|
|
{0, NULL, 0, NULL, NULL}};
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Set Spline Type";
|
2009-03-29 02:15:13 +00:00
|
|
|
ot->idname= "CURVE_OT_spline_type_set";
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= set_spline_type_exec;
|
2009-09-08 07:35:07 +00:00
|
|
|
ot->invoke= WM_menu_invoke;
|
2009-02-11 23:02:21 +00:00
|
|
|
ot->poll= ED_operator_editcurve;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
/* properties */
|
2010-01-15 22:40:33 +00:00
|
|
|
ot->prop= RNA_def_enum(ot->srna, "type", type_items, CU_POLY, "Type", "Spline type");
|
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)
|
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
|
|
|
|
sethandlesNurb(editnurb, RNA_enum_get(op->ptr, "type"));
|
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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 */
|
|
|
|
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", ""},
|
2010-12-09 19:06:45 +00:00
|
|
|
{3, "TOGGLE_FREE_ALIGN", 0, "Toggle Free/Align", ""},
|
2009-06-16 00:52: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 */
|
|
|
|
ot->name= "Set Handle Type";
|
2009-03-29 02:15:13 +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 */
|
2010-12-14 10:17:13 +00:00
|
|
|
ot->invoke= WM_menu_invoke;
|
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
|
|
|
ot->exec= set_handle_type_exec;
|
|
|
|
ot->poll= ED_operator_editcurve;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
/* properties */
|
2010-12-14 10:17:13 +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
|
|
|
}
|
|
|
|
|
|
|
|
/***************** 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;
|
|
|
|
|
|
|
|
if(base==NULL || tot==0) return;
|
|
|
|
|
|
|
|
/* reverse knots */
|
|
|
|
a= tot;
|
|
|
|
fp1= base;
|
|
|
|
fp2= fp1+(a-1);
|
|
|
|
a/= 2;
|
|
|
|
while(fp1!=fp2 && a>0) {
|
|
|
|
SWAP(float, *fp1, *fp2);
|
|
|
|
a--;
|
|
|
|
fp1++;
|
|
|
|
fp2--;
|
|
|
|
}
|
|
|
|
/* and make in increasing order again */
|
|
|
|
a= tot;
|
|
|
|
fp1= base;
|
|
|
|
fp2=tempf= MEM_mallocN(sizeof(float)*a, "switchdirect");
|
|
|
|
while(a--) {
|
|
|
|
fp2[0]= fabs(fp1[1]-fp1[0]);
|
|
|
|
fp1++;
|
|
|
|
fp2++;
|
|
|
|
}
|
|
|
|
|
|
|
|
a= tot-1;
|
|
|
|
fp1= base;
|
|
|
|
fp2= tempf;
|
|
|
|
fp1[0]= 0.0;
|
|
|
|
fp1++;
|
|
|
|
while(a--) {
|
|
|
|
fp1[0]= fp1[-1]+fp2[0];
|
|
|
|
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;
|
|
|
|
|
|
|
|
SWAP(short, nu->pntsu, nu->pntsv);
|
|
|
|
SWAP(short, nu->orderu, nu->orderv);
|
|
|
|
SWAP(short, nu->resolu, nu->resolv);
|
|
|
|
SWAP(short, nu->flagu, nu->flagv);
|
|
|
|
|
|
|
|
SWAP(float *, nu->knotsu, nu->knotsv);
|
|
|
|
switchdirection_knots(nu->knotsv, KNOTSV(nu) );
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MEM_freeN(temp);
|
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
static int is_u_selected(Nurb *nu, int u)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
|
|
|
BPoint *bp;
|
|
|
|
int v;
|
|
|
|
|
|
|
|
/* what about resolu == 2? */
|
|
|
|
bp= nu->bp+u;
|
|
|
|
for(v=0; v<nu->pntsv-1; v++, bp+=nu->pntsu) {
|
|
|
|
if(v) if(bp->f1 & SELECT) return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct NurbSort {
|
|
|
|
struct NurbSort *next, *prev;
|
|
|
|
Nurb *nu;
|
|
|
|
float vec[3];
|
|
|
|
} NurbSort;
|
|
|
|
|
|
|
|
static ListBase nsortbase= {0, 0};
|
|
|
|
/* static NurbSort *nusmain; */ /* this var seems to go unused... at least in this file */
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
static void make_selection_list_nurb(ListBase *editnurb)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
|
|
|
ListBase nbase= {0, 0};
|
|
|
|
NurbSort *nus, *nustest, *headdo, *taildo;
|
|
|
|
Nurb *nu;
|
|
|
|
BPoint *bp;
|
|
|
|
float dist, headdist, taildist;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
if( isNurbsel(nu) ) {
|
|
|
|
|
|
|
|
nus = (NurbSort*)MEM_callocN(sizeof(NurbSort), "sort");
|
|
|
|
BLI_addhead(&nbase, nus);
|
|
|
|
nus->nu= nu;
|
|
|
|
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu;
|
|
|
|
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++;
|
|
|
|
}
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_v3_fl(nus->vec, 1.0/(float)nu->pntsu);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* just add the first one */
|
|
|
|
nus= nbase.first;
|
|
|
|
BLI_remlink(&nbase, nus);
|
|
|
|
BLI_addtail( &nsortbase, nus);
|
|
|
|
|
|
|
|
/* now add, either at head or tail, the closest one */
|
|
|
|
while(nbase.first) {
|
|
|
|
|
|
|
|
headdist= taildist= 1.0e30;
|
|
|
|
headdo= taildo= 0;
|
|
|
|
|
|
|
|
nustest= nbase.first;
|
|
|
|
while(nustest) {
|
2009-11-10 20:43:45 +00:00
|
|
|
dist= len_v3v3(nustest->vec, ((NurbSort *)nsortbase.first)->vec);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
if(dist<headdist) {
|
|
|
|
headdist= dist;
|
|
|
|
headdo= nustest;
|
|
|
|
}
|
2009-11-10 20:43:45 +00:00
|
|
|
dist= len_v3v3(nustest->vec, ((NurbSort *)nsortbase.last)->vec);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
if(dist<taildist) {
|
|
|
|
taildist= dist;
|
|
|
|
taildo= nustest;
|
|
|
|
}
|
|
|
|
nustest= nustest->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(headdist<taildist) {
|
|
|
|
BLI_remlink(&nbase, headdo);
|
|
|
|
BLI_addhead(&nsortbase, headdo);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
BLI_remlink(&nbase, taildo);
|
|
|
|
BLI_addtail(&nsortbase, taildo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu2)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
|
|
|
BPoint *bp, *bp1, *bp2, *temp;
|
|
|
|
float len1, len2;
|
|
|
|
int origu, u, v;
|
|
|
|
|
|
|
|
/* 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 */
|
|
|
|
|
|
|
|
if( is_u_selected(nu1, nu1->pntsu-1) );
|
|
|
|
else {
|
2010-03-23 22:09:33 +00:00
|
|
|
/* For 2D curves blender uses orderv=0. It doesn't make any sense mathematically. */
|
|
|
|
/* but after rotating orderu=0 will be confusing. */
|
|
|
|
if (nu1->orderv == 0) nu1->orderv= 1;
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
rotate_direction_nurb(nu1);
|
|
|
|
if( is_u_selected(nu1, nu1->pntsu-1) );
|
|
|
|
else {
|
|
|
|
rotate_direction_nurb(nu1);
|
|
|
|
if( is_u_selected(nu1, nu1->pntsu-1) );
|
|
|
|
else {
|
|
|
|
rotate_direction_nurb(nu1);
|
|
|
|
if( is_u_selected(nu1, nu1->pntsu-1) );
|
|
|
|
else {
|
|
|
|
/* rotate again, now its OK! */
|
|
|
|
if(nu1->pntsv!=1) rotate_direction_nurb(nu1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 2nd nurbs: u = 0 selected */
|
|
|
|
if( is_u_selected(nu2, 0) );
|
|
|
|
else {
|
2010-03-23 22:09:33 +00:00
|
|
|
if (nu2->orderv == 0) nu2->orderv= 1;
|
2009-01-14 12:26:45 +00:00
|
|
|
rotate_direction_nurb(nu2);
|
|
|
|
if( is_u_selected(nu2, 0) );
|
|
|
|
else {
|
|
|
|
rotate_direction_nurb(nu2);
|
|
|
|
if( is_u_selected(nu2, 0) );
|
|
|
|
else {
|
|
|
|
rotate_direction_nurb(nu2);
|
|
|
|
if( is_u_selected(nu2, 0) );
|
|
|
|
else {
|
|
|
|
/* rotate again, now its OK! */
|
|
|
|
if(nu1->pntsu==1) rotate_direction_nurb(nu1);
|
|
|
|
if(nu2->pntsv!=1) rotate_direction_nurb(nu2);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nu1->pntsv != nu2->pntsv ) {
|
2009-02-11 23:02:21 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Resolution doesn't match");
|
2009-01-14 12:26:45 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ok, now nu1 has the rightmost collumn and nu2 the leftmost collumn selected */
|
|
|
|
/* maybe we need a 'v' flip of nu2? */
|
|
|
|
|
|
|
|
bp1= nu1->bp+nu1->pntsu-1;
|
|
|
|
bp2= nu2->bp;
|
|
|
|
len1= 0.0;
|
|
|
|
|
|
|
|
for(v=0; v<nu1->pntsv; v++, bp1+=nu1->pntsu, bp2+=nu2->pntsu) {
|
2009-11-10 20:43:45 +00:00
|
|
|
len1+= len_v3v3(bp1->vec, bp2->vec);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bp1= nu1->bp + nu1->pntsu-1;
|
|
|
|
bp2= nu2->bp + nu2->pntsu*(nu2->pntsv-1);
|
|
|
|
len2= 0.0;
|
|
|
|
|
|
|
|
for(v=0; v<nu1->pntsv; v++, bp1+=nu1->pntsu, bp2-=nu2->pntsu) {
|
2009-11-10 20:43:45 +00:00
|
|
|
len2+= len_v3v3(bp1->vec, bp2->vec);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* merge */
|
|
|
|
origu= nu1->pntsu;
|
|
|
|
nu1->pntsu+= nu2->pntsu;
|
2010-03-23 22:09:33 +00:00
|
|
|
if(nu1->orderu<3 && nu1->orderu<nu1->pntsu) nu1->orderu++;
|
|
|
|
if(nu1->orderv<3 && nu1->orderv<nu1->pntsv) nu1->orderv++;
|
2009-01-14 12:26:45 +00:00
|
|
|
temp= nu1->bp;
|
|
|
|
nu1->bp= MEM_mallocN(nu1->pntsu*nu1->pntsv*sizeof(BPoint), "mergeBP");
|
|
|
|
|
|
|
|
bp= nu1->bp;
|
|
|
|
bp1= temp;
|
|
|
|
|
|
|
|
for(v=0; v<nu1->pntsv; v++) {
|
|
|
|
|
|
|
|
/* switch direction? */
|
|
|
|
if(len1<len2) bp2= nu2->bp + v*nu2->pntsu;
|
|
|
|
else bp2= nu2->bp + (nu1->pntsv-v-1)*nu2->pntsu;
|
|
|
|
|
|
|
|
for(u=0; u<nu1->pntsu; u++, bp++) {
|
|
|
|
if(u<origu) {
|
|
|
|
*bp= *bp1; bp1++;
|
|
|
|
select_bpoint(bp, SELECT, 1, HIDDEN);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*bp= *bp2; bp2++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu1->type == CU_NURBS) {
|
2009-01-14 12:26:45 +00:00
|
|
|
/* merge knots */
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(nu1);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
/* make knots, for merged curved for example */
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_v(nu1);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MEM_freeN(temp);
|
|
|
|
BLI_remlink(editnurb, nu2);
|
|
|
|
freeNurb(nu2);
|
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
static int merge_nurb(bContext *C, wmOperator *op)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
NurbSort *nus1, *nus2;
|
|
|
|
int ok= 1;
|
|
|
|
|
|
|
|
make_selection_list_nurb(editnurb);
|
|
|
|
|
|
|
|
if(nsortbase.first == nsortbase.last) {
|
|
|
|
BLI_freelistN(&nsortbase);
|
2009-02-11 23:02:21 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Too few selections to merge.");
|
|
|
|
return OPERATOR_CANCELLED;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nus1= nsortbase.first;
|
|
|
|
nus2= nus1->next;
|
|
|
|
|
|
|
|
/* resolution match, to avoid uv rotations */
|
|
|
|
if(nus1->nu->pntsv==1) {
|
|
|
|
if(nus1->nu->pntsu==nus2->nu->pntsu || nus1->nu->pntsu==nus2->nu->pntsv);
|
|
|
|
else ok= 0;
|
|
|
|
}
|
|
|
|
else if(nus2->nu->pntsv==1) {
|
|
|
|
if(nus2->nu->pntsu==nus1->nu->pntsu || nus2->nu->pntsu==nus1->nu->pntsv);
|
|
|
|
else ok= 0;
|
|
|
|
}
|
|
|
|
else if( nus1->nu->pntsu==nus2->nu->pntsu || nus1->nu->pntsv==nus2->nu->pntsv);
|
|
|
|
else if( nus1->nu->pntsu==nus2->nu->pntsv || nus1->nu->pntsv==nus2->nu->pntsu);
|
|
|
|
else {
|
|
|
|
ok= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ok==0) {
|
2009-02-11 23:02:21 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Resolution doesn't 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
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
while(nus2) {
|
2009-02-11 23:02:21 +00:00
|
|
|
merge_2_nurb(op, editnurb, nus1->nu, nus2->nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
nus2= nus2->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
BLI_freelistN(&nsortbase);
|
|
|
|
|
|
|
|
set_actNurb(obedit, NULL);
|
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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 */
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-09-08 07:35:07 +00:00
|
|
|
Curve *cu= obedit->data;
|
2010-07-25 11:57:36 +00:00
|
|
|
ListBase *nubase= curve_get_editcurve(obedit);
|
2009-01-14 12:26:45 +00:00
|
|
|
Nurb *nu, *nu1=0, *nu2=0;
|
|
|
|
BPoint *bp;
|
|
|
|
float *fp, offset;
|
2010-11-21 19:29:08 +00:00
|
|
|
int a, ok= 0;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
/* first decide if this is a surface merge! */
|
2010-07-25 11:57:36 +00:00
|
|
|
if(obedit->type==OB_SURF) nu= nubase->first;
|
2009-01-14 12:26:45 +00:00
|
|
|
else nu= NULL;
|
|
|
|
|
|
|
|
while(nu) {
|
|
|
|
if( isNurbsel(nu) ) {
|
|
|
|
|
|
|
|
if(nu->pntsu>1 && nu->pntsv>1) break;
|
2009-09-08 07:35:07 +00:00
|
|
|
if(isNurbsel_count(cu, nu)>1) break;
|
|
|
|
if(isNurbsel_count(cu, nu)==1) {
|
2009-01-14 12:26:45 +00:00
|
|
|
/* only 1 selected, not first or last, a little complex, but intuitive */
|
|
|
|
if(nu->pntsv==1) {
|
|
|
|
if( (nu->bp->f1 & SELECT) || ((nu->bp+nu->pntsu-1)->f1 & SELECT));
|
|
|
|
else break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
if(nu)
|
|
|
|
return merge_nurb(C, op);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
/* find both nurbs and points, nu1 will be put behind nu2 */
|
2010-07-25 11:57:36 +00:00
|
|
|
for(nu= nubase->first; nu; nu= nu->next) {
|
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
|
|
|
if((nu->flagu & CU_NURB_CYCLIC)==0) { /* not cyclic */
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
if(nu1==0) {
|
2011-01-04 08:00:16 +00:00
|
|
|
if( BEZSELECTED_HIDDENHANDLES(cu, nu->bezt) ) nu1= nu;
|
2009-01-14 12:26:45 +00:00
|
|
|
else {
|
2011-01-04 08:00:16 +00:00
|
|
|
if( BEZSELECTED_HIDDENHANDLES(cu, &(nu->bezt[nu->pntsu-1])) ) {
|
2009-01-14 12:26:45 +00:00
|
|
|
nu1= nu;
|
|
|
|
switchdirectionNurb(nu);
|
2010-07-25 11:57:36 +00:00
|
|
|
keyData_switchDirectionNurb(cu, nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(nu2==0) {
|
2011-01-04 08:00:16 +00:00
|
|
|
if( BEZSELECTED_HIDDENHANDLES(cu, nu->bezt) ) {
|
2009-01-14 12:26:45 +00:00
|
|
|
nu2= nu;
|
|
|
|
switchdirectionNurb(nu);
|
2010-07-25 11:57:36 +00:00
|
|
|
keyData_switchDirectionNurb(cu, nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-01-04 08:00:16 +00:00
|
|
|
if( BEZSELECTED_HIDDENHANDLES(cu, &(nu->bezt[nu->pntsu-1])) ) {
|
2009-01-14 12:26:45 +00:00
|
|
|
nu2= nu;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else break;
|
|
|
|
}
|
|
|
|
else if(nu->pntsv==1) {
|
|
|
|
bp= nu->bp;
|
|
|
|
if(nu1==0) {
|
|
|
|
if( bp->f1 & SELECT) nu1= nu;
|
|
|
|
else {
|
|
|
|
bp= bp+(nu->pntsu-1);
|
|
|
|
if( bp->f1 & SELECT ) {
|
|
|
|
nu1= nu;
|
|
|
|
switchdirectionNurb(nu);
|
2010-07-25 11:57:36 +00:00
|
|
|
keyData_switchDirectionNurb(cu, nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(nu2==0) {
|
|
|
|
if( bp->f1 & SELECT ) {
|
|
|
|
nu2= nu;
|
|
|
|
switchdirectionNurb(nu);
|
2010-07-25 11:57:36 +00:00
|
|
|
keyData_switchDirectionNurb(cu, nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp= bp+(nu->pntsu-1);
|
|
|
|
if( bp->f1 & SELECT ) {
|
|
|
|
nu2= nu;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if((nu1 && nu2) && (nu1!=nu2)) {
|
|
|
|
if( nu1->type==nu2->type) {
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu1->type == CU_BEZIER) {
|
2011-01-04 08:00:16 +00:00
|
|
|
BezTriple *bezt =
|
2009-01-14 12:26:45 +00:00
|
|
|
(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);
|
|
|
|
ED_curve_beztcpy(cu->editnurb, bezt+nu2->pntsu, nu1->bezt, nu1->pntsu);
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
MEM_freeN(nu1->bezt);
|
|
|
|
nu1->bezt= bezt;
|
|
|
|
nu1->pntsu+= nu2->pntsu;
|
2010-07-25 11:57:36 +00:00
|
|
|
BLI_remlink(nubase, nu2);
|
2009-01-14 12:26:45 +00:00
|
|
|
freeNurb(nu2); nu2= NULL;
|
|
|
|
calchandlesNurb(nu1);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
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);
|
|
|
|
ED_curve_bpcpy(cu->editnurb, bp+nu2->pntsu, nu1->bp, nu1->pntsu);
|
2009-01-14 12:26:45 +00:00
|
|
|
MEM_freeN(nu1->bp);
|
|
|
|
nu1->bp= bp;
|
|
|
|
|
|
|
|
a= nu1->pntsu+nu1->orderu;
|
|
|
|
|
|
|
|
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 */
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu1->type == CU_NURBS) {
|
2009-01-14 12:26:45 +00:00
|
|
|
if(nu1->knotsu==NULL) {
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(nu1);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
fp= MEM_mallocN(sizeof(float)*KNOTSU(nu1), "addsegment3");
|
|
|
|
memcpy(fp, nu1->knotsu, sizeof(float)*a);
|
|
|
|
MEM_freeN(nu1->knotsu);
|
|
|
|
nu1->knotsu= fp;
|
|
|
|
|
|
|
|
|
|
|
|
offset= nu1->knotsu[a-1] +1.0;
|
|
|
|
fp= nu1->knotsu+a;
|
|
|
|
for(a=0; a<nu2->pntsu; a++, fp++) {
|
|
|
|
if(nu2->knotsu)
|
|
|
|
*fp= offset+nu2->knotsu[a+1];
|
|
|
|
else
|
|
|
|
*fp = offset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
freeNurb(nu2); nu2= NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
set_actNurb(obedit, NULL); /* for selected */
|
2010-11-21 19:29:08 +00:00
|
|
|
ok= 1;
|
|
|
|
} else if(nu1 && !nu2 && nu1->type == CU_BEZIER) {
|
|
|
|
if(!(nu1->flagu & CU_NURB_CYCLIC)) {
|
|
|
|
if(BEZSELECTED_HIDDENHANDLES(cu, nu1->bezt) &&
|
2011-01-04 07:32:26 +00:00
|
|
|
BEZSELECTED_HIDDENHANDLES(cu, nu1->bezt+(nu1->pntsu-1))) {
|
2010-11-21 19:29:08 +00:00
|
|
|
nu1->flagu|= CU_NURB_CYCLIC;
|
|
|
|
calchandlesNurb(nu1);
|
|
|
|
ok= 1;
|
|
|
|
}
|
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
}
|
2010-11-21 19:29:08 +00:00
|
|
|
|
|
|
|
if(!ok) {
|
2009-02-11 23:02:21 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Can't make segment");
|
|
|
|
return OPERATOR_CANCELLED;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
2010-11-21 19:29:08 +00:00
|
|
|
|
2010-12-20 19:47:16 +00:00
|
|
|
if(ED_curve_updateAnimPaths(obedit))
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, obedit);
|
2010-12-06 17:20:22 +00:00
|
|
|
|
2010-11-21 19:29:08 +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 */
|
|
|
|
ot->name= "Make Segment";
|
|
|
|
ot->idname= "CURVE_OT_make_segment";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= make_segment_exec;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
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
|
|
|
/***************** pick select from 3d view **********************/
|
2009-02-11 23:02:21 +00:00
|
|
|
|
2009-11-24 04:59:52 +00:00
|
|
|
int mouse_nurb(bContext *C, short mval[2], int extend)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-04 17:40:50 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
Curve *cu= obedit->data;
|
2009-09-08 07:35:07 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
2009-01-14 12:26:45 +00:00
|
|
|
ViewContext vc;
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt=0;
|
|
|
|
BPoint *bp=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
|
|
|
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);
|
|
|
|
|
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
|
|
|
location[0]= mval[0];
|
|
|
|
location[1]= mval[1];
|
|
|
|
hand= findnearestNurbvert(&vc, 1, location, &nu, &bezt, &bp);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
if(bezt || bp) {
|
|
|
|
if(extend==0) {
|
|
|
|
|
|
|
|
setflagsNurb(editnurb, 0);
|
|
|
|
|
|
|
|
if(bezt) {
|
|
|
|
|
2010-04-30 04:48:40 +00:00
|
|
|
if(hand==1) {
|
|
|
|
select_beztriple(bezt, SELECT, 1, HIDDEN);
|
|
|
|
cu->lastsel= bezt;
|
|
|
|
} else {
|
|
|
|
if(hand==0) bezt->f1|= SELECT;
|
|
|
|
else bezt->f3|= SELECT;
|
|
|
|
|
|
|
|
cu->lastsel= NULL;
|
|
|
|
}
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
else {
|
2010-04-30 04:48:40 +00:00
|
|
|
cu->lastsel= bp;
|
2009-01-14 12:26:45 +00:00
|
|
|
select_bpoint(bp, SELECT, 1, HIDDEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(bezt) {
|
|
|
|
if(hand==1) {
|
2010-04-30 04:48:40 +00:00
|
|
|
if(bezt->f2 & SELECT) {
|
|
|
|
select_beztriple(bezt, DESELECT, 1, HIDDEN);
|
|
|
|
if (bezt == cu->lastsel) cu->lastsel = NULL;
|
|
|
|
} else {
|
|
|
|
select_beztriple(bezt, SELECT, 1, HIDDEN);
|
|
|
|
cu->lastsel= bezt;
|
|
|
|
}
|
2009-01-14 12:26:45 +00:00
|
|
|
} else if(hand==0) {
|
|
|
|
bezt->f1 ^= SELECT;
|
|
|
|
} else {
|
|
|
|
bezt->f3 ^= SELECT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2010-04-30 04:48:40 +00:00
|
|
|
if(bp->f1 & SELECT) {
|
|
|
|
select_bpoint(bp, DESELECT, 1, HIDDEN);
|
|
|
|
if (cu->lastsel == bp) cu->lastsel = NULL;
|
|
|
|
} else {
|
2009-01-14 12:26:45 +00:00
|
|
|
select_bpoint(bp, SELECT, 1, HIDDEN);
|
2010-04-30 04:48:40 +00:00
|
|
|
cu->lastsel= bp;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-11-24 04:59:52 +00:00
|
|
|
if(nu!=get_actNurb(obedit))
|
|
|
|
set_actNurb(obedit, nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-11-24 04:59:52 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-11-24 04:59:52 +00:00
|
|
|
return 0;
|
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.
|
|
|
|
*/
|
2010-09-30 05:26:36 +00:00
|
|
|
static int spin_nurb(float viewmat[][4], Object *obedit, float *axis, float *cent)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2010-07-25 11:57:36 +00:00
|
|
|
Curve *cu= (Curve*)obedit->data;
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
2010-01-12 01:50:34 +00:00
|
|
|
float si,phi,n[3],q[4],cmat[3][3],tmat[3][3],imat[3][3];
|
|
|
|
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];
|
2009-02-11 23:02:21 +00:00
|
|
|
short a,ok, changed= 0;
|
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
|
|
|
|
|
|
|
normalize_v3_v3(n, axis);
|
2010-01-12 01:50:34 +00:00
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
phi= M_PI/8.0;
|
|
|
|
q[0]= cos(phi);
|
|
|
|
si= sin(phi);
|
|
|
|
q[1]= n[0]*si;
|
|
|
|
q[2]= n[1]*si;
|
|
|
|
q[3]= n[2]*si;
|
2009-11-10 20:43:45 +00:00
|
|
|
quat_to_mat3( cmat,q);
|
|
|
|
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);
|
2010-09-30 05:26:36 +00:00
|
|
|
scalemat1[0][0]= M_SQRT2;
|
|
|
|
scalemat1[1][1]= M_SQRT2;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-11-10 20:43:45 +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);
|
2010-09-30 05:26:36 +00:00
|
|
|
scalemat2[0][0]/= M_SQRT2;
|
|
|
|
scalemat2[1][1]/= M_SQRT2;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-11-10 20:43:45 +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
|
|
|
|
|
|
|
ok= 1;
|
|
|
|
|
|
|
|
for(a=0;a<7;a++) {
|
2010-09-30 05:26:36 +00:00
|
|
|
ok= extrudeflagNurb(cu->editnurb, 1);
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
if(ok==0)
|
|
|
|
return changed;
|
|
|
|
|
|
|
|
changed= 1;
|
|
|
|
|
2010-09-30 05:26:36 +00:00
|
|
|
rotateflagNurb(editnurb, SELECT, cent, rotmat);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-09-30 05:26:36 +00:00
|
|
|
if( (a & SELECT)==0 ) {
|
|
|
|
rotateflagNurb(editnurb, SELECT, cent, scalemat1);
|
|
|
|
weightflagNurb(editnurb, SELECT, 0.25*M_SQRT2);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rotateflagNurb(editnurb, SELECT, cent, scalemat2);
|
|
|
|
weightflagNurb(editnurb, SELECT, 4.0/M_SQRT2);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ok) {
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
if(isNurbsel(nu)) {
|
|
|
|
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;
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_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)
|
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2011-01-03 10:47:36 +00:00
|
|
|
RegionView3D *rv3d= ED_view3d_context_rv3d(C);
|
|
|
|
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);
|
|
|
|
|
2011-01-03 10:47:36 +00:00
|
|
|
if(rv3d)
|
|
|
|
copy_m4_m4(viewmat, rv3d->viewmat);
|
|
|
|
else
|
|
|
|
unit_m4(viewmat);
|
|
|
|
|
|
|
|
if(!spin_nurb(viewmat, obedit, axis, cent)) {
|
2009-02-11 23:02:21 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Can't spin");
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
2010-12-20 19:47:16 +00:00
|
|
|
if(ED_curve_updateAnimPaths(obedit))
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, obedit);
|
2010-12-06 17:20:22 +00:00
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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
|
|
|
}
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int spin_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
|
2010-01-12 01:50:34 +00:00
|
|
|
{
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
RegionView3D *rv3d= ED_view3d_context_rv3d(C);
|
2011-01-03 10:47:36 +00:00
|
|
|
float axis[3]= {0.0f, 0.0f, 1.0f};
|
|
|
|
|
|
|
|
if(rv3d)
|
|
|
|
copy_v3_v3(axis, rv3d->viewinv[2]);
|
2010-01-12 01:50:34 +00:00
|
|
|
|
|
|
|
RNA_float_set_array(op->ptr, "center", give_cursor(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 */
|
|
|
|
ot->name= "Spin";
|
|
|
|
ot->idname= "CURVE_OT_spin";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= spin_exec;
|
2010-01-12 01:50:34 +00:00
|
|
|
ot->invoke = spin_invoke;
|
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
|
|
|
ot->poll= ED_operator_editsurf;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2010-01-12 01:50:34 +00:00
|
|
|
|
2010-08-26 00:06:10 +00:00
|
|
|
RNA_def_float_vector_xyz(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX);
|
2010-01-12 01:50:34 +00:00
|
|
|
RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX);
|
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
|
|
|
/***************** add vertex operator **********************/
|
2009-02-11 23:02:21 +00:00
|
|
|
|
2009-02-13 17:37:01 +00:00
|
|
|
static int addvert_Nurb(bContext *C, short mode, float location[3])
|
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
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2010-07-25 11:57:36 +00:00
|
|
|
Curve *cu= (Curve*)obedit->data;
|
|
|
|
EditNurb *editnurb= cu->editnurb;
|
2010-12-19 19:22:17 +00:00
|
|
|
Nurb *nu, *newnu= NULL;
|
2009-01-14 12:26:45 +00:00
|
|
|
BezTriple *bezt, *newbezt = NULL;
|
|
|
|
BPoint *bp, *newbp = NULL;
|
2009-02-13 17:37:01 +00:00
|
|
|
float mat[3][3],imat[3][3], temp[3];
|
2010-12-19 19:22:17 +00:00
|
|
|
int ok= 0;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_m3_m4(mat, obedit->obmat);
|
|
|
|
invert_m3_m3(imat,mat);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-07-25 11:57:36 +00:00
|
|
|
findselectedNurbvert(&editnurb->nurbs, &nu, &bezt, &bp);
|
2010-11-21 03:45:35 +00:00
|
|
|
|
2010-12-19 01:59:52 +00:00
|
|
|
if ((nu == NULL) || (nu->type==CU_BEZIER && bezt==NULL) || (nu->type!=CU_BEZIER && bp==NULL)) {
|
2010-12-20 17:42:17 +00:00
|
|
|
if(cu->actnu >= 0 && mode!='e') {
|
2010-12-19 19:22:17 +00:00
|
|
|
nu= BLI_findlink(&editnurb->nurbs, cu->actnu);
|
|
|
|
|
|
|
|
if(nu->type==CU_BEZIER) {
|
|
|
|
newbezt= (BezTriple*)MEM_callocN(sizeof(BezTriple), "addvert_Nurb");
|
|
|
|
newbezt->radius= 1;
|
|
|
|
newbezt->alfa= 0;
|
|
|
|
BEZ_SEL(newbezt);
|
|
|
|
newbezt->h2= newbezt->h1= HD_AUTO;
|
|
|
|
|
|
|
|
newnu= (Nurb*)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu");
|
|
|
|
memcpy(newnu, nu, sizeof(Nurb));
|
|
|
|
BLI_addtail(&editnurb->nurbs, newnu);
|
|
|
|
set_actNurb(obedit, newnu);
|
|
|
|
newnu->bezt= newbezt;
|
|
|
|
newnu->pntsu= 1;
|
|
|
|
|
|
|
|
temp[0] = 1;
|
|
|
|
temp[1] = 0;
|
|
|
|
temp[2] = 0;
|
|
|
|
copy_v3_v3(newbezt->vec[1], location);
|
|
|
|
sub_v3_v3(newbezt->vec[1], obedit->obmat[3]);
|
|
|
|
sub_v3_v3v3(newbezt->vec[0], newbezt->vec[1],temp);
|
|
|
|
add_v3_v3v3(newbezt->vec[2], newbezt->vec[1],temp);
|
|
|
|
|
|
|
|
ok= 1;
|
|
|
|
} else if(nu->pntsv == 1) {
|
|
|
|
newbp= (BPoint*)MEM_callocN(sizeof(BPoint), "addvert_Nurb5");
|
|
|
|
newbp->radius= 1;
|
|
|
|
newbp->alfa= 0;
|
|
|
|
newbp->f1|= SELECT;
|
|
|
|
cu->lastsel= newbp;
|
|
|
|
|
|
|
|
newnu= (Nurb*)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu");
|
|
|
|
memcpy(newnu, nu, sizeof(Nurb));
|
|
|
|
BLI_addtail(&editnurb->nurbs, newnu);
|
|
|
|
set_actNurb(obedit, newnu);
|
|
|
|
newnu->bp= newbp;
|
|
|
|
newnu->orderu= 2;
|
|
|
|
newnu->pntsu= 1;
|
|
|
|
|
|
|
|
copy_v3_v3(newbp->vec, location);
|
|
|
|
sub_v3_v3(newbp->vec, obedit->obmat[3]);
|
|
|
|
mul_m3_v3(imat,newbp->vec);
|
|
|
|
newbp->vec[3]= 1.0;
|
|
|
|
|
|
|
|
newnu->knotsu= newnu->knotsv= 0;
|
|
|
|
nurbs_knot_calc_u(newnu);
|
|
|
|
|
|
|
|
ok= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!ok)
|
|
|
|
return OPERATOR_CANCELLED;
|
2010-11-21 03:45:35 +00:00
|
|
|
}
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-12-19 19:22:17 +00:00
|
|
|
if(!ok && nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
/* which bezpoint? */
|
2010-12-19 19:22:17 +00:00
|
|
|
if(bezt== (nu->bezt+nu->pntsu-1)) { /* last */
|
2009-01-14 12:26:45 +00:00
|
|
|
BEZ_DESEL(bezt);
|
|
|
|
newbezt =
|
|
|
|
(BezTriple*)MEM_callocN((nu->pntsu+1) * sizeof(BezTriple), "addvert_Nurb");
|
2010-12-19 19:22:17 +00:00
|
|
|
ED_curve_beztcpy(editnurb, newbezt, nu->bezt, nu->pntsu);
|
|
|
|
*(newbezt+nu->pntsu)= *bezt;
|
2009-01-14 12:26:45 +00:00
|
|
|
VECCOPY(temp, bezt->vec[1]);
|
|
|
|
MEM_freeN(nu->bezt);
|
|
|
|
nu->bezt= newbezt;
|
2010-12-19 19:22:17 +00:00
|
|
|
newbezt+= nu->pntsu;
|
|
|
|
BEZ_SEL(newbezt);
|
|
|
|
cu->lastsel= newbezt;
|
|
|
|
newbezt->h2= newbezt->h1;
|
|
|
|
bezt= nu->bezt+nu->pntsu-1;
|
|
|
|
ok= 1;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
2010-12-19 19:22:17 +00:00
|
|
|
else if(bezt== nu->bezt) { /* first */
|
2009-01-14 12:26:45 +00:00
|
|
|
BEZ_DESEL(bezt);
|
|
|
|
newbezt =
|
|
|
|
(BezTriple*)MEM_callocN((nu->pntsu+1) * sizeof(BezTriple), "addvert_Nurb");
|
2010-12-19 19:22:17 +00:00
|
|
|
ED_curve_beztcpy(editnurb, newbezt+1, bezt, nu->pntsu);
|
|
|
|
*newbezt= *bezt;
|
|
|
|
BEZ_SEL(newbezt);
|
|
|
|
cu->lastsel= newbezt;
|
|
|
|
newbezt->h2= newbezt->h1;
|
2009-01-14 12:26:45 +00:00
|
|
|
VECCOPY(temp, bezt->vec[1]);
|
|
|
|
MEM_freeN(nu->bezt);
|
|
|
|
nu->bezt= newbezt;
|
2010-12-19 19:22:17 +00:00
|
|
|
bezt= newbezt+1;
|
|
|
|
ok= 1;
|
|
|
|
}
|
|
|
|
else if(mode!='e') {
|
|
|
|
BEZ_DESEL(bezt);
|
|
|
|
newbezt= (BezTriple*)MEM_callocN(sizeof(BezTriple), "addvert_Nurb");
|
|
|
|
*newbezt= *bezt;
|
2009-01-14 12:26:45 +00:00
|
|
|
BEZ_SEL(newbezt);
|
|
|
|
newbezt->h2= newbezt->h1;
|
2010-12-19 19:22:17 +00:00
|
|
|
VECCOPY(temp, bezt->vec[1]);
|
|
|
|
|
|
|
|
newnu= (Nurb*)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu");
|
|
|
|
memcpy(newnu, nu, sizeof(Nurb));
|
|
|
|
BLI_addtail(&editnurb->nurbs, newnu);
|
|
|
|
set_actNurb(obedit, newnu);
|
|
|
|
newnu->bezt= newbezt;
|
|
|
|
newnu->pntsu= 1;
|
|
|
|
|
|
|
|
cu->lastsel= newbezt;
|
|
|
|
|
|
|
|
bezt= newbezt;
|
|
|
|
ok= 1;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
else bezt= 0;
|
|
|
|
|
|
|
|
if(bezt) {
|
2010-12-19 19:22:17 +00:00
|
|
|
if(!newnu) nu->pntsu++;
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
if(mode=='e') {
|
2010-04-23 23:57:00 +00:00
|
|
|
copy_v3_v3(newbezt->vec[0], bezt->vec[0]);
|
|
|
|
copy_v3_v3(newbezt->vec[1], bezt->vec[1]);
|
|
|
|
copy_v3_v3(newbezt->vec[2], bezt->vec[2]);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
else {
|
2010-04-23 23:57:00 +00:00
|
|
|
copy_v3_v3(newbezt->vec[1], location);
|
|
|
|
sub_v3_v3(newbezt->vec[1], obedit->obmat[3]);
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_m3_v3(imat,newbezt->vec[1]);
|
|
|
|
sub_v3_v3v3(temp, newbezt->vec[1],temp);
|
|
|
|
add_v3_v3v3(newbezt->vec[0], bezt->vec[0],temp);
|
|
|
|
add_v3_v3v3(newbezt->vec[2], bezt->vec[2],temp);
|
2010-12-19 19:22:17 +00:00
|
|
|
|
|
|
|
if(newnu) calchandlesNurb(newnu);
|
|
|
|
else calchandlesNurb(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-12-19 19:22:17 +00:00
|
|
|
else if(!ok && nu->pntsv==1) {
|
2009-01-14 12:26:45 +00:00
|
|
|
/* which b-point? */
|
|
|
|
if(bp== nu->bp) { /* first */
|
|
|
|
bp->f1= 0;
|
|
|
|
newbp =
|
|
|
|
(BPoint*)MEM_callocN((nu->pntsu+1) * sizeof(BPoint), "addvert_Nurb3");
|
2010-07-25 11:57:36 +00:00
|
|
|
ED_curve_bpcpy(editnurb, newbp+1, bp, nu->pntsu);
|
2009-01-14 12:26:45 +00:00
|
|
|
*newbp= *bp;
|
2010-12-19 19:22:17 +00:00
|
|
|
newbp->f1|= SELECT;
|
|
|
|
cu->lastsel= newbp;
|
2009-01-14 12:26:45 +00:00
|
|
|
MEM_freeN(nu->bp);
|
|
|
|
nu->bp= newbp;
|
|
|
|
bp= newbp + 1;
|
2010-12-19 19:22:17 +00:00
|
|
|
ok= 1;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
else if(bp== (nu->bp+nu->pntsu-1)) { /* last */
|
|
|
|
bp->f1= 0;
|
|
|
|
newbp =
|
|
|
|
(BPoint*)MEM_callocN((nu->pntsu+1) * sizeof(BPoint), "addvert_Nurb4");
|
2010-07-25 11:57:36 +00:00
|
|
|
ED_curve_bpcpy(editnurb, newbp, nu->bp, nu->pntsu);
|
2009-01-14 12:26:45 +00:00
|
|
|
*(newbp+nu->pntsu)= *bp;
|
|
|
|
MEM_freeN(nu->bp);
|
|
|
|
nu->bp= newbp;
|
|
|
|
newbp+= nu->pntsu;
|
2010-12-19 19:22:17 +00:00
|
|
|
newbp->f1|= SELECT;
|
|
|
|
cu->lastsel= newbp;
|
2009-01-14 12:26:45 +00:00
|
|
|
bp= newbp - 1;
|
2010-12-19 19:22:17 +00:00
|
|
|
ok= 1;
|
|
|
|
}
|
|
|
|
else if(mode!='e') {
|
|
|
|
bp->f1= 0;
|
|
|
|
newbp= (BPoint*)MEM_callocN(sizeof(BPoint), "addvert_Nurb5");
|
|
|
|
*newbp= *bp;
|
|
|
|
newbp->f1|= SELECT;
|
|
|
|
cu->lastsel= newbp;
|
|
|
|
|
|
|
|
newnu= (Nurb*)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu");
|
|
|
|
memcpy(newnu, nu, sizeof(Nurb));
|
|
|
|
BLI_addtail(&editnurb->nurbs, newnu);
|
|
|
|
set_actNurb(obedit, newnu);
|
|
|
|
newnu->bp= newbp;
|
|
|
|
newnu->orderu= 2;
|
|
|
|
newnu->pntsu= 1;
|
|
|
|
newnu->knotsu= newnu->knotsv= NULL;
|
|
|
|
|
|
|
|
bp= newbp;
|
|
|
|
ok= 1;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
else bp= 0;
|
|
|
|
|
|
|
|
if(bp) {
|
|
|
|
if(mode=='e') {
|
2010-04-23 23:57:00 +00:00
|
|
|
copy_v3_v3(newbp->vec, bp->vec);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
else {
|
2010-04-23 23:57:00 +00:00
|
|
|
copy_v3_v3(newbp->vec, location);
|
|
|
|
sub_v3_v3(newbp->vec, obedit->obmat[3]);
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_m3_v3(imat,newbp->vec);
|
2009-01-14 12:26:45 +00:00
|
|
|
newbp->vec[3]= 1.0;
|
2010-12-19 19:22:17 +00:00
|
|
|
|
|
|
|
if(!newnu && nu->orderu<4 && nu->orderu<=nu->pntsu)
|
|
|
|
nu->orderu++;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
2010-12-19 19:22:17 +00:00
|
|
|
|
|
|
|
if(!newnu) {
|
|
|
|
nu->pntsu++;
|
|
|
|
nurbs_knot_calc_u(nu);
|
|
|
|
} else nurbs_knot_calc_u(newnu);
|
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
|
|
|
// XXX retopo_do_all();
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-12-19 19:22:17 +00:00
|
|
|
if(ok) {
|
|
|
|
test2DNurb(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-12-20 19:47:16 +00:00
|
|
|
if(ED_curve_updateAnimPaths(obedit))
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, obedit);
|
2010-12-06 17:20:22 +00:00
|
|
|
|
2010-12-19 19:22:17 +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
|
|
|
|
2010-12-19 19:22:17 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return OPERATOR_CANCELLED;
|
2009-02-11 23:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int add_vertex_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2009-02-13 17:37:01 +00:00
|
|
|
float location[3];
|
|
|
|
|
|
|
|
RNA_float_get_array(op->ptr, "location", location);
|
|
|
|
return addvert_Nurb(C, 0, location);
|
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
|
|
|
|
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 add_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
{
|
2009-02-13 17:37:01 +00:00
|
|
|
RegionView3D *rv3d= CTX_wm_region_view3d(C);
|
|
|
|
ViewContext vc;
|
2010-03-23 20:41:19 +00:00
|
|
|
float location[3] = {0.0f, 0.0f, 0.0f};
|
2009-02-13 17:37:01 +00:00
|
|
|
short mval[2];
|
|
|
|
|
|
|
|
if(rv3d && !RNA_property_is_set(op->ptr, "location")) {
|
|
|
|
view3d_set_viewcontext(C, &vc);
|
|
|
|
|
|
|
|
mval[0]= event->x - vc.ar->winrct.xmin;
|
|
|
|
mval[1]= event->y - vc.ar->winrct.ymin;
|
|
|
|
|
|
|
|
view3d_get_view_aligned_coordinate(&vc, location, mval);
|
|
|
|
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 */
|
|
|
|
ot->name= "Add Vertex";
|
2009-04-12 22:43:07 +00:00
|
|
|
ot->idname= "CURVE_OT_vertex_add";
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= add_vertex_exec;
|
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
|
|
|
ot->invoke= add_vertex_invoke;
|
|
|
|
ot->poll= ED_operator_editcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-02-13 17:37:01 +00:00
|
|
|
|
|
|
|
/* properties */
|
2010-08-26 00:06:10 +00:00
|
|
|
RNA_def_float_vector_xyz(ot->srna, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "Location to add new vertex at.", -1e4, 1e4);
|
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
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int extrude_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-02-11 23:02:21 +00:00
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-09-08 07:35:07 +00:00
|
|
|
Curve *cu= obedit->data;
|
2010-07-25 11:57:36 +00:00
|
|
|
EditNurb *editnurb= cu->editnurb;
|
2009-01-14 12:26:45 +00:00
|
|
|
Nurb *nu;
|
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? */
|
2010-07-25 11:57:36 +00:00
|
|
|
for(nu= editnurb->nurbs.first; nu; nu= nu->next)
|
2009-09-08 07:35:07 +00:00
|
|
|
if(nu->pntsv==1 && isNurbsel_count(cu, nu)==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
|
|
|
break;
|
|
|
|
|
|
|
|
if(obedit->type==OB_CURVE || nu) {
|
2009-02-13 17:37:01 +00:00
|
|
|
addvert_Nurb(C, 'e', NULL);
|
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 {
|
|
|
|
if(extrudeflagNurb(editnurb, 1)) { /* '1'= flag */
|
2010-12-20 19:47:16 +00:00
|
|
|
if(ED_curve_updateAnimPaths(obedit))
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, obedit);
|
2010-12-06 17:20:22 +00:00
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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
|
|
|
}
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int extrude_invoke(bContext *C, wmOperator *op, 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
|
|
|
{
|
|
|
|
if(extrude_exec(C, op) == OPERATOR_FINISHED) {
|
|
|
|
RNA_int_set(op->ptr, "mode", TFM_TRANSLATION);
|
2009-12-10 10:36:32 +00:00
|
|
|
WM_operator_name_call(C, "TRANSFORM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr);
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
void CURVE_OT_extrude(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Extrude";
|
|
|
|
ot->idname= "CURVE_OT_extrude";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= extrude_exec;
|
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
|
|
|
ot->invoke= extrude_invoke;
|
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
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 */
|
|
|
|
RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX);
|
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
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-09-08 07:35:07 +00:00
|
|
|
Curve *cu= obedit->data;
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
2009-03-17 21:44:58 +00:00
|
|
|
int a, direction= RNA_enum_get(op->ptr, "direction");
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
if( nu->pntsu>1 || nu->pntsv>1) {
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_POLY) {
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu->pntsu;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a--) {
|
|
|
|
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++;
|
|
|
|
}
|
|
|
|
}
|
2009-09-08 00:23:33 +00:00
|
|
|
else if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu->pntsu;
|
|
|
|
bezt= nu->bezt;
|
|
|
|
while(a--) {
|
2009-09-08 07:35:07 +00:00
|
|
|
if( BEZSELECTED_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++;
|
|
|
|
}
|
|
|
|
calchandlesNurb(nu);
|
|
|
|
}
|
2009-09-08 00:23:33 +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 */
|
|
|
|
a= nu->pntsu;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a--) {
|
|
|
|
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;
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(nu); /* 1==u type is ignored for cyclic curves */
|
2009-01-14 12:26:45 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(nu->type==CU_NURBS) {
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a--) {
|
|
|
|
|
|
|
|
if( bp->f1 & SELECT) {
|
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
|
|
|
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;
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(nu); /* 1==u type is ignored for cyclic curves */
|
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
|
|
|
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;
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_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
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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;
|
|
|
|
}
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int toggle_cyclic_invoke(bContext *C, wmOperator *op, 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
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
|
|
|
ListBase *editnurb= curve_get_editcurve(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;
|
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
if(nu->pntsu>1 || nu->pntsv>1) {
|
|
|
|
if(nu->type==CU_NURBS) {
|
use ICON_NULL define rather then 0, makes UI calls less confusing. (no functional change)
eg: uiItemR(row, &dvar_ptr, "type", 0, "", 0); -> uiItemR(row, &dvar_ptr, "type", 0, "", ICON_NULL);
2010-12-23 02:43:40 +00:00
|
|
|
pup= uiPupMenuBegin(C, "Direction", ICON_NULL);
|
2009-04-22 18:39:44 +00:00
|
|
|
layout= uiPupMenuLayout(pup);
|
|
|
|
uiItemsEnumO(layout, op->type->idname, "direction");
|
|
|
|
uiPupMenuEnd(C, pup);
|
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_CANCELLED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
{
|
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 EnumPropertyItem direction_items[]= {
|
2009-06-16 00:52:21 +00:00
|
|
|
{0, "CYCLIC_U", 0, "Cyclic U", ""},
|
|
|
|
{1, "CYCLIC_V", 0, "Cyclic V", ""},
|
|
|
|
{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 */
|
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
|
|
|
ot->name= "Toggle Cyclic";
|
2009-03-29 02:15:13 +00:00
|
|
|
ot->idname= "CURVE_OT_cyclic_toggle";
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
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
|
|
|
ot->exec= toggle_cyclic_exec;
|
|
|
|
ot->invoke= toggle_cyclic_invoke;
|
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
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 */
|
|
|
|
RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction", "Direction to make surface cyclic in.");
|
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
|
|
|
/***************** select linked operator ******************/
|
2009-02-11 23:02:21 +00:00
|
|
|
|
2010-11-21 18:50:53 +00:00
|
|
|
static int select_linked_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2010-11-21 18:50:53 +00:00
|
|
|
Curve *cu= (Curve*)obedit->data;
|
|
|
|
EditNurb *editnurb= cu->editnurb;
|
|
|
|
ListBase *nurbs= &editnurb->nurbs;
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
for(nu= nurbs->first; nu; nu= nu->next) {
|
|
|
|
if(nu->type == CU_BEZIER) {
|
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a--) {
|
|
|
|
if( (bezt->f1 & SELECT) || (bezt->f2 & SELECT) || (bezt->f3 & SELECT) ) {
|
|
|
|
a= nu->pntsu;
|
|
|
|
bezt= nu->bezt;
|
|
|
|
while(a--) {
|
|
|
|
select_beztriple(bezt, SELECT, 1, VISIBLE);
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
while(a--) {
|
|
|
|
if( bp->f1 & 1 ) {
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a--) {
|
|
|
|
select_bpoint(bp, SELECT, 1, VISIBLE);
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int select_linked_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
|
|
|
|
{
|
|
|
|
return select_linked_exec(C, op);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CURVE_OT_select_linked(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Select Linked All";
|
|
|
|
ot->idname= "CURVE_OT_select_linked";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= select_linked_exec;
|
|
|
|
ot->invoke= select_linked_invoke;
|
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
/* properties */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***************** select linked pick operator ******************/
|
|
|
|
|
|
|
|
static int select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
|
|
|
ARegion *ar= CTX_wm_region(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
ViewContext vc;
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
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 a, location[2], deselect;
|
|
|
|
|
|
|
|
deselect= RNA_boolean_get(op->ptr, "deselect");
|
2010-11-21 18:50:53 +00:00
|
|
|
location[0]= event->x - ar->winrct.xmin;
|
|
|
|
location[1]= event->y - ar->winrct.ymin;
|
|
|
|
|
2010-01-26 17:06:28 +00:00
|
|
|
view3d_operator_needs_opengl(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
|
|
|
view3d_set_viewcontext(C, &vc);
|
2010-11-21 18:50:53 +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
|
|
|
findnearestNurbvert(&vc, 1, location, &nu, &bezt, &bp);
|
2009-02-11 23:02:21 +00:00
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
if(bezt) {
|
|
|
|
a= nu->pntsu;
|
|
|
|
bezt= nu->bezt;
|
|
|
|
while(a--) {
|
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
|
|
|
if(deselect) select_beztriple(bezt, DESELECT, 1, VISIBLE);
|
2009-01-14 12:26:45 +00:00
|
|
|
else select_beztriple(bezt, SELECT, 1, VISIBLE);
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(bp) {
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a--) {
|
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
|
|
|
if(deselect) select_bpoint(bp, DESELECT, 1, VISIBLE);
|
2009-01-14 12:26:45 +00:00
|
|
|
else select_bpoint(bp, SELECT, 1, VISIBLE);
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->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
|
|
|
|
2010-11-21 18:50:53 +00:00
|
|
|
return OPERATOR_FINISHED;
|
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-11-21 18:50:53 +00:00
|
|
|
void CURVE_OT_select_linked_pick(wmOperatorType *ot)
|
2009-02-11 23:02:21 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Select Linked";
|
2010-11-21 18:50:53 +00:00
|
|
|
ot->idname= "CURVE_OT_select_linked_pick";
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/* api callbacks */
|
2010-11-21 18:50:53 +00:00
|
|
|
ot->invoke= select_linked_pick_invoke;
|
|
|
|
ot->poll= ED_operator_editsurfcurve_region_view3d;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
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 */
|
|
|
|
RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect linked control points rather than selecting them.");
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/***************** select row operator **********************/
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int select_row_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
Curve *cu= obedit->data;
|
2009-09-08 07:35:07 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
2009-01-14 12:26:45 +00:00
|
|
|
static BPoint *last=0;
|
|
|
|
static int direction=0;
|
|
|
|
Nurb *nu;
|
|
|
|
BPoint *bp;
|
|
|
|
int u = 0, v = 0, a, b, ok=0;
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
if(editnurb->first==0)
|
|
|
|
return OPERATOR_CANCELLED;
|
2010-04-30 04:48:40 +00:00
|
|
|
if(cu->lastsel==NULL)
|
2009-02-11 23:02:21 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
/* find the correct nurb and toggle with u of v */
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
bp= nu->bp;
|
|
|
|
for(v=0; v<nu->pntsv; v++) {
|
|
|
|
for(u=0; u<nu->pntsu; u++, bp++) {
|
2010-04-30 04:48:40 +00:00
|
|
|
if(bp==cu->lastsel) {
|
2009-01-14 12:26:45 +00:00
|
|
|
if(bp->f1 & SELECT) {
|
|
|
|
ok= 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(ok) break;
|
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
if(ok) {
|
2010-04-30 04:48:40 +00:00
|
|
|
if(last==cu->lastsel) {
|
2009-01-14 12:26:45 +00:00
|
|
|
direction= 1-direction;
|
|
|
|
setflagsNurb(editnurb, 0);
|
|
|
|
}
|
2010-04-30 04:48:40 +00:00
|
|
|
last= cu->lastsel;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
bp= nu->bp;
|
|
|
|
for(a=0; a<nu->pntsv; a++) {
|
|
|
|
for(b=0; b<nu->pntsu; b++, bp++) {
|
|
|
|
if(direction) {
|
|
|
|
if(a==v) select_bpoint(bp, SELECT, 1, VISIBLE);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(b==u) select_bpoint(bp, SELECT, 1, VISIBLE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
break;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
|
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_select_row(wmOperatorType *ot)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Select Control Point Row";
|
|
|
|
ot->idname= "CURVE_OT_select_row";
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= select_row_exec;
|
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
|
|
|
ot->poll= ED_operator_editsurf;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***************** select next operator **********************/
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int select_next_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-02-11 23:02:21 +00:00
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
select_adjacent_cp(editnurb, 1, 0, SELECT);
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CURVE_OT_select_next(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Select Next";
|
|
|
|
ot->idname= "CURVE_OT_select_next";
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= select_next_exec;
|
|
|
|
ot->poll= ED_operator_editcurve;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/***************** select previous operator **********************/
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int select_previous_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
|
|
|
|
select_adjacent_cp(editnurb, -1, 0, SELECT);
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CURVE_OT_select_previous(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Select Previous";
|
|
|
|
ot->idname= "CURVE_OT_select_previous";
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= select_previous_exec;
|
|
|
|
ot->poll= ED_operator_editcurve;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/***************** select more operator **********************/
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int select_more_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
|
|
|
BPoint *bp, *tempbp;
|
|
|
|
int a;
|
|
|
|
short sel= 0;
|
|
|
|
short *selbpoints;
|
|
|
|
|
|
|
|
/* note that NURBS surface is a special case because we mimic */
|
|
|
|
/* the behaviour of "select more" of mesh tools. */
|
|
|
|
/* The algorithm is designed to work in planar cases so it */
|
|
|
|
/* may not be optimal always (example: end of NURBS sphere) */
|
|
|
|
if(obedit->type==OB_SURF) {
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
selbpoints= MEM_callocN(sizeof(short)*a-nu->pntsu, "selectlist");
|
|
|
|
while(a > 0) {
|
|
|
|
if((selbpoints[a]!=1) && (bp->hide==0) && (bp->f1 & SELECT)) {
|
|
|
|
/* upper control point */
|
|
|
|
if(a%nu->pntsu != 0) {
|
|
|
|
tempbp= bp-1;
|
|
|
|
if(!(tempbp->f1 & SELECT)) select_bpoint(tempbp, SELECT, 1, VISIBLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* left control point. select only if it is not selected already */
|
|
|
|
if(a-nu->pntsu > 0) {
|
|
|
|
sel= 0;
|
|
|
|
tempbp= bp+nu->pntsu;
|
|
|
|
if(!(tempbp->f1 & SELECT)) sel= select_bpoint(tempbp, SELECT, 1, VISIBLE);
|
|
|
|
/* make sure selected bpoint is discarded */
|
|
|
|
if(sel == 1) selbpoints[a-nu->pntsu]= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* right control point */
|
|
|
|
if(a+nu->pntsu < nu->pntsu*nu->pntsv) {
|
|
|
|
tempbp= bp-nu->pntsu;
|
|
|
|
if(!(tempbp->f1 & SELECT)) select_bpoint(tempbp, SELECT, 1, VISIBLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* lower control point. skip next bp in case selection was made */
|
|
|
|
if(a%nu->pntsu != 1) {
|
|
|
|
sel= 0;
|
|
|
|
tempbp= bp+1;
|
|
|
|
if(!(tempbp->f1 & 1)) sel= select_bpoint(tempbp, SELECT, 1, VISIBLE);
|
|
|
|
if(sel) {
|
|
|
|
bp++;
|
|
|
|
a--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bp++;
|
|
|
|
a--;
|
|
|
|
}
|
|
|
|
|
|
|
|
MEM_freeN(selbpoints);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
select_adjacent_cp(editnurb, 1, 0, SELECT);
|
|
|
|
select_adjacent_cp(editnurb, -1, 0, SELECT);
|
|
|
|
}
|
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CURVE_OT_select_more(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Select More";
|
|
|
|
ot->idname= "CURVE_OT_select_more";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= select_more_exec;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/******************** select less operator *****************/
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
/* basic method: deselect if control point doesn't have all neighbours selected */
|
2010-10-15 01:36:14 +00:00
|
|
|
static int select_less_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
|
|
|
BPoint *bp;
|
|
|
|
BezTriple *bezt;
|
|
|
|
int a;
|
|
|
|
short sel= 0, lastsel= 0;
|
|
|
|
short *selbpoints;
|
|
|
|
|
|
|
|
if(obedit->type==OB_SURF) {
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
selbpoints= MEM_callocN(sizeof(short)*a, "selectlist");
|
|
|
|
while(a--) {
|
|
|
|
if((bp->hide==0) && (bp->f1 & SELECT)) {
|
|
|
|
sel= 0;
|
|
|
|
|
|
|
|
/* check if neighbours have been selected */
|
|
|
|
/* edges of surface are an exception */
|
|
|
|
if((a+1)%nu->pntsu==0) sel++;
|
|
|
|
else {
|
|
|
|
bp--;
|
|
|
|
if((selbpoints[a+1]==1) || ((bp->hide==0) && (bp->f1 & SELECT))) sel++;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((a+1)%nu->pntsu==1) sel++;
|
|
|
|
else {
|
|
|
|
bp++;
|
|
|
|
if((bp->hide==0) && (bp->f1 & SELECT)) sel++;
|
|
|
|
bp--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(a+1 > nu->pntsu*nu->pntsv-nu->pntsu) sel++;
|
|
|
|
else {
|
|
|
|
bp-=nu->pntsu;
|
|
|
|
if((selbpoints[a+nu->pntsu]==1) || ((bp->hide==0) && (bp->f1 & SELECT))) sel++;
|
|
|
|
bp+=nu->pntsu;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(a < nu->pntsu) sel++;
|
|
|
|
else {
|
|
|
|
bp+=nu->pntsu;
|
|
|
|
if((bp->hide==0) && (bp->f1 & SELECT)) sel++;
|
|
|
|
bp-=nu->pntsu;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(sel!=4) {
|
|
|
|
select_bpoint(bp, DESELECT, 1, VISIBLE);
|
|
|
|
selbpoints[a]= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else lastsel= 0;
|
|
|
|
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
|
|
|
|
MEM_freeN(selbpoints);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
lastsel=0;
|
|
|
|
/* check what type of curve/nurb it is */
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu->pntsu;
|
|
|
|
bezt= nu->bezt;
|
|
|
|
while(a--) {
|
|
|
|
if((bezt->hide==0) && (bezt->f2 & SELECT)) {
|
|
|
|
if(lastsel==1) sel= 1;
|
|
|
|
else sel= 0;
|
|
|
|
|
|
|
|
/* check if neighbours have been selected */
|
|
|
|
/* first and last are exceptions */
|
|
|
|
if(a==nu->pntsu-1) sel++;
|
|
|
|
else {
|
|
|
|
bezt--;
|
|
|
|
if((bezt->hide==0) && (bezt->f2 & SELECT)) sel++;
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(a==0) sel++;
|
|
|
|
else {
|
|
|
|
bezt++;
|
|
|
|
if((bezt->hide==0) && (bezt->f2 & SELECT)) sel++;
|
|
|
|
bezt--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(sel!=2) {
|
|
|
|
select_beztriple(bezt, DESELECT, 1, VISIBLE);
|
|
|
|
lastsel= 1;
|
|
|
|
}
|
|
|
|
else lastsel= 0;
|
|
|
|
}
|
|
|
|
else lastsel= 0;
|
|
|
|
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a--) {
|
|
|
|
if((lastsel==0) && (bp->hide==0) && (bp->f1 & SELECT)) {
|
|
|
|
if(lastsel!=0) sel= 1;
|
|
|
|
else sel= 0;
|
|
|
|
|
|
|
|
/* first and last are exceptions */
|
|
|
|
if(a==nu->pntsu*nu->pntsv-1) sel++;
|
|
|
|
else {
|
|
|
|
bp--;
|
|
|
|
if((bp->hide==0) && (bp->f1 & SELECT)) sel++;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(a==0) sel++;
|
|
|
|
else {
|
|
|
|
bp++;
|
|
|
|
if((bp->hide==0) && (bp->f1 & SELECT)) sel++;
|
|
|
|
bp--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(sel!=2) {
|
|
|
|
select_bpoint(bp, DESELECT, 1, VISIBLE);
|
|
|
|
lastsel= 1;
|
|
|
|
}
|
|
|
|
else lastsel= 0;
|
|
|
|
}
|
|
|
|
else lastsel= 0;
|
|
|
|
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CURVE_OT_select_less(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Select Less";
|
|
|
|
ot->idname= "CURVE_OT_select_less";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= select_less_exec;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/********************** select random *********************/
|
|
|
|
|
2010-01-11 05:32:01 +00:00
|
|
|
static void selectrandom_curve(ListBase *editnurb, float randfac)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
2010-01-11 05:32:01 +00:00
|
|
|
int a;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-01-11 05:32:01 +00:00
|
|
|
BLI_srand( BLI_rand() ); /* random seed */
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-01-11 05:32:01 +00:00
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a--) {
|
2010-01-11 05:32:01 +00:00
|
|
|
if (BLI_frand() < randfac)
|
|
|
|
select_beztriple(bezt, SELECT, 1, VISIBLE);
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
2010-01-11 05:32:01 +00:00
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
while(a--) {
|
2010-01-11 05:32:01 +00:00
|
|
|
if (BLI_frand() < randfac)
|
|
|
|
select_bpoint(bp, SELECT, 1, VISIBLE);
|
2009-01-14 12:26:45 +00:00
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-01-11 05:32:01 +00:00
|
|
|
}
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-01-11 05:32:01 +00:00
|
|
|
static int select_random_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
2009-02-11 23:02:21 +00:00
|
|
|
|
2010-01-11 05:32:01 +00:00
|
|
|
if(!RNA_boolean_get(op->ptr, "extend"))
|
|
|
|
CU_deselect_all(obedit);
|
|
|
|
|
|
|
|
selectrandom_curve(editnurb, RNA_float_get(op->ptr, "percent")/100.0f);
|
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
|
|
|
|
|
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_select_random(wmOperatorType *ot)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Select Random";
|
|
|
|
ot->idname= "CURVE_OT_select_random";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= select_random_exec;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
/* properties */
|
2010-01-11 05:32:01 +00:00
|
|
|
RNA_def_float_percentage(ot->srna, "percent", 50.f, 0.0f, 100.0f, "Percent", "Percentage of elements to select randomly.", 0.f, 100.0f);
|
|
|
|
RNA_def_boolean(ot->srna, "extend", FALSE, "Extend Selection", "Extend selection instead of deselecting everything first.");
|
2009-02-11 23:02:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-10 17:32:11 +00:00
|
|
|
/********************* every nth number of point *******************/
|
2009-02-11 23:02:21 +00:00
|
|
|
|
2010-05-10 17:32:11 +00:00
|
|
|
static int point_on_nurb(Nurb *nu, void *point)
|
|
|
|
{
|
|
|
|
if (nu->bezt) {
|
|
|
|
BezTriple *bezt= (BezTriple*)point;
|
|
|
|
return bezt >= nu->bezt && bezt < nu->bezt + nu->pntsu;
|
|
|
|
} else {
|
|
|
|
BPoint *bp= (BPoint*)point;
|
|
|
|
return bp >= nu->bp && bp < nu->bp + nu->pntsu * nu->pntsv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void select_nth_bezt(Nurb *nu, BezTriple *bezt, int nth)
|
|
|
|
{
|
|
|
|
int a, start;
|
|
|
|
|
|
|
|
start= bezt - nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
bezt= nu->bezt + a - 1;
|
|
|
|
|
|
|
|
while (a--) {
|
|
|
|
if (abs(start - a) % nth) {
|
|
|
|
select_beztriple(bezt, DESELECT, 1, HIDDEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
bezt--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void select_nth_bp(Nurb *nu, BPoint *bp, int nth)
|
|
|
|
{
|
|
|
|
int a, startrow, startpnt;
|
|
|
|
int dist, row, pnt;
|
|
|
|
|
|
|
|
startrow= (bp - nu->bp) / nu->pntsu;
|
|
|
|
startpnt= (bp - nu->bp) % nu->pntsu;
|
|
|
|
|
|
|
|
a= nu->pntsu * nu->pntsv;
|
|
|
|
bp= nu->bp + a - 1;
|
|
|
|
row = nu->pntsv - 1;
|
|
|
|
pnt = nu->pntsu - 1;
|
|
|
|
|
|
|
|
while (a--) {
|
|
|
|
dist= abs(pnt - startpnt) + abs(row - startrow);
|
|
|
|
if (dist % nth) {
|
|
|
|
select_bpoint(bp, DESELECT, 1, HIDDEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
pnt--;
|
|
|
|
if (pnt < 0) {
|
|
|
|
pnt= nu->pntsu - 1;
|
|
|
|
row--;
|
|
|
|
}
|
|
|
|
|
|
|
|
bp--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int CU_select_nth(Object *obedit, int nth)
|
|
|
|
{
|
|
|
|
Curve *cu= (Curve*)obedit->data;
|
2010-07-25 11:57:36 +00:00
|
|
|
ListBase *nubase= ED_curve_editnurbs(cu);
|
2010-05-10 17:32:11 +00:00
|
|
|
Nurb *nu;
|
|
|
|
int ok=0;
|
|
|
|
|
|
|
|
/* Search nurb to which selected point belongs to */
|
|
|
|
nu= nubase->first;
|
|
|
|
while (nu) {
|
|
|
|
if (point_on_nurb(nu, cu->lastsel)) {
|
|
|
|
ok= 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ok) return 0;
|
|
|
|
|
|
|
|
if (nu->bezt) {
|
|
|
|
select_nth_bezt(nu, cu->lastsel, nth);
|
|
|
|
} else {
|
|
|
|
select_nth_bp(nu, cu->lastsel, nth);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int select_nth_exec(bContext *C, wmOperator *op)
|
2009-02-11 23:02:21 +00:00
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2010-05-10 17:32:11 +00:00
|
|
|
int nth= RNA_int_get(op->ptr, "nth");
|
|
|
|
|
|
|
|
if (!CU_select_nth(obedit, nth)) {
|
|
|
|
if (obedit->type == OB_SURF) {
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "Surface hasn't got active point");
|
|
|
|
} else {
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "Curve hasn't got active point");
|
|
|
|
}
|
|
|
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
2010-05-10 17:32:11 +00:00
|
|
|
void CURVE_OT_select_nth(wmOperatorType *ot)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
/* identifiers */
|
2010-05-10 17:32:11 +00:00
|
|
|
ot->name= "Select Nth";
|
|
|
|
ot->description= "";
|
|
|
|
ot->idname= "CURVE_OT_select_nth";
|
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/* api callbacks */
|
2010-05-10 17:32:11 +00:00
|
|
|
ot->exec= select_nth_exec;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2010-05-10 17:32:11 +00:00
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-05-10 17:32:11 +00:00
|
|
|
RNA_def_int(ot->srna, "nth", 2, 2, 100, "Nth Selection", "", 1, INT_MAX);
|
2009-02-11 23:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/********************** add duplicate operator *********************/
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int duplicate_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-02-11 23:02:21 +00:00
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
adduplicateflagNurb(obedit, 1);
|
2010-03-12 16:43:04 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, 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
|
|
|
}
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int duplicate_invoke(bContext *C, wmOperator *op, 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
|
|
|
{
|
|
|
|
duplicate_exec(C, op);
|
|
|
|
|
|
|
|
RNA_int_set(op->ptr, "mode", TFM_TRANSLATION);
|
2009-12-10 10:36:32 +00:00
|
|
|
WM_operator_name_call(C, "TRANSFORM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr);
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CURVE_OT_duplicate(wmOperatorType *ot)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
/* identifiers */
|
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
|
|
|
ot->name= "Duplicate";
|
|
|
|
ot->idname= "CURVE_OT_duplicate";
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
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
|
|
|
ot->exec= duplicate_exec;
|
|
|
|
ot->invoke= duplicate_invoke;
|
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
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 */
|
|
|
|
RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX);
|
2009-02-11 23:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/********************** delete operator *********************/
|
|
|
|
|
|
|
|
static int delete_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-09-08 07:35:07 +00:00
|
|
|
Curve *cu= obedit->data;
|
2010-07-25 11:57:36 +00:00
|
|
|
EditNurb *editnurb= cu->editnurb;
|
|
|
|
ListBase *nubase= &editnurb->nurbs;
|
2009-01-14 12:26:45 +00:00
|
|
|
Nurb *nu, *next, *nu1;
|
|
|
|
BezTriple *bezt, *bezt1, *bezt2;
|
|
|
|
BPoint *bp, *bp1, *bp2;
|
2009-02-11 23:02:21 +00:00
|
|
|
int a, cut= 0, type= RNA_enum_get(op->ptr, "type");
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
if(obedit->type==OB_SURF) {
|
2010-07-25 11:57:36 +00:00
|
|
|
if(type==0) {
|
|
|
|
deleteflagNurb(C, op, 1);
|
|
|
|
} else {
|
|
|
|
keyIndex_delNurbList(editnurb, nubase);
|
|
|
|
freeNurblist(nubase);
|
2010-12-20 19:47:16 +00:00
|
|
|
|
|
|
|
if(ED_curve_updateAnimPaths(obedit))
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, obedit);
|
2010-07-25 11:57:36 +00:00
|
|
|
}
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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
|
|
|
if(type==0) {
|
2009-01-14 12:26:45 +00:00
|
|
|
/* first loop, can we remove entire pieces? */
|
2010-07-25 11:57:36 +00:00
|
|
|
nu= nubase->first;
|
2009-01-14 12:26:45 +00:00
|
|
|
while(nu) {
|
|
|
|
next= nu->next;
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
if(a) {
|
|
|
|
while(a) {
|
2009-09-08 07:35:07 +00:00
|
|
|
if( BEZSELECTED_HIDDENHANDLES(cu, bezt) );
|
2009-01-14 12:26:45 +00:00
|
|
|
else break;
|
|
|
|
a--;
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
if(a==0) {
|
2010-07-25 11:57:36 +00:00
|
|
|
BLI_remlink(nubase, nu);
|
|
|
|
keyIndex_delNurb(editnurb, nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
freeNurb(nu); nu= NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
if(a) {
|
|
|
|
while(a) {
|
|
|
|
if(bp->f1 & SELECT);
|
|
|
|
else break;
|
|
|
|
a--;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
if(a==0) {
|
2010-07-25 11:57:36 +00:00
|
|
|
BLI_remlink(nubase, nu);
|
|
|
|
keyIndex_delNurb(editnurb, nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
freeNurb(nu); nu= NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Never allow the order to exceed the number of points
|
|
|
|
- note, this is ok but changes unselected nurbs, disable for now */
|
|
|
|
/*
|
2009-09-08 00:23:33 +00:00
|
|
|
if ((nu!= NULL) && (nu->type == CU_NURBS)) {
|
2009-01-14 12:26:45 +00:00
|
|
|
clamp_nurb_order_u(nu);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
nu= next;
|
|
|
|
}
|
|
|
|
/* 2nd loop, delete small pieces: just for curves */
|
2010-07-25 11:57:36 +00:00
|
|
|
nu= nubase->first;
|
2009-01-14 12:26:45 +00:00
|
|
|
while(nu) {
|
|
|
|
next= nu->next;
|
2009-02-11 23:02:21 +00:00
|
|
|
type= 0;
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2010-07-25 11:57:36 +00:00
|
|
|
int delta= 0;
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt= nu->bezt;
|
|
|
|
for(a=0;a<nu->pntsu;a++) {
|
2009-09-08 07:35:07 +00:00
|
|
|
if( BEZSELECTED_HIDDENHANDLES(cu, bezt) ) {
|
2009-01-14 12:26:45 +00:00
|
|
|
memmove(bezt, bezt+1, (nu->pntsu-a-1)*sizeof(BezTriple));
|
2010-07-25 11:57:36 +00:00
|
|
|
keyIndex_delBezt(editnurb, bezt + delta);
|
2010-12-06 21:18:08 +00:00
|
|
|
keyIndex_updateBezt(editnurb, bezt + 1, bezt, nu->pntsu-a-1);
|
2009-01-14 12:26:45 +00:00
|
|
|
nu->pntsu--;
|
|
|
|
a--;
|
2009-02-11 23:02:21 +00:00
|
|
|
type= 1;
|
2010-07-25 11:57:36 +00:00
|
|
|
delta++;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
else bezt++;
|
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
if(type) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt1 =
|
|
|
|
(BezTriple*)MEM_mallocN((nu->pntsu) * sizeof(BezTriple), "delNurb");
|
|
|
|
memcpy(bezt1, nu->bezt, (nu->pntsu)*sizeof(BezTriple) );
|
2010-12-06 21:18:08 +00:00
|
|
|
keyIndex_updateBezt(editnurb, nu->bezt, bezt1, nu->pntsu);
|
2009-01-14 12:26:45 +00:00
|
|
|
MEM_freeN(nu->bezt);
|
|
|
|
nu->bezt= bezt1;
|
|
|
|
calchandlesNurb(nu);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(nu->pntsv==1) {
|
2010-07-25 11:57:36 +00:00
|
|
|
int delta= 0;
|
2009-01-14 12:26:45 +00:00
|
|
|
bp= nu->bp;
|
|
|
|
|
|
|
|
for(a=0;a<nu->pntsu;a++) {
|
|
|
|
if( bp->f1 & SELECT ) {
|
|
|
|
memmove(bp, bp+1, (nu->pntsu-a-1)*sizeof(BPoint));
|
2010-07-25 11:57:36 +00:00
|
|
|
keyIndex_delBP(editnurb, bp + delta);
|
2010-12-06 21:18:08 +00:00
|
|
|
keyIndex_updateBP(editnurb, bp+1, bp, nu->pntsu-a-1);
|
2009-01-14 12:26:45 +00:00
|
|
|
nu->pntsu--;
|
|
|
|
a--;
|
2009-02-11 23:02:21 +00:00
|
|
|
type= 1;
|
2010-07-25 11:57:36 +00:00
|
|
|
delta++;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
if(type) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bp1 = (BPoint*)MEM_mallocN(nu->pntsu * sizeof(BPoint), "delNurb2");
|
|
|
|
memcpy(bp1, nu->bp, (nu->pntsu)*sizeof(BPoint) );
|
2010-12-06 21:18:08 +00:00
|
|
|
keyIndex_updateBP(editnurb, nu->bp, bp1, nu->pntsu);
|
2009-01-14 12:26:45 +00:00
|
|
|
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 */
|
|
|
|
/*
|
2009-09-08 00:23:33 +00:00
|
|
|
if (nu->type == CU_NURBS) {
|
2009-01-14 12:26:45 +00:00
|
|
|
clamp_nurb_order_u(nu);
|
|
|
|
}*/
|
|
|
|
}
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
nu= next;
|
|
|
|
}
|
|
|
|
}
|
2009-02-11 23:02:21 +00:00
|
|
|
else if(type==1) { /* erase segment */
|
2009-01-14 12:26:45 +00:00
|
|
|
/* find the 2 selected points */
|
2011-01-06 01:29:13 +00:00
|
|
|
bezt1= bezt2= NULL;
|
|
|
|
bp1= bp2= NULL;
|
|
|
|
nu1= NULL;
|
|
|
|
for(nu= nubase->first; nu; nu= nu->next) {
|
2009-01-14 12:26:45 +00:00
|
|
|
next= nu->next;
|
2009-09-08 00:23:33 +00:00
|
|
|
if(nu->type == CU_BEZIER) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt= nu->bezt;
|
|
|
|
for(a=0; a<nu->pntsu-1; a++) {
|
2009-09-08 07:35:07 +00:00
|
|
|
if( BEZSELECTED_HIDDENHANDLES(cu, bezt) ) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt1= bezt;
|
|
|
|
bezt2= bezt+1;
|
|
|
|
if( (bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & SELECT) ) ;
|
|
|
|
else { /* maybe do not make cyclic */
|
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
|
|
|
if(a==0 && (nu->flagu & CU_NURB_CYCLIC) ) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt2= bezt+(nu->pntsu-1);
|
|
|
|
if( (bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & 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;
|
2010-11-21 19:01:18 +00:00
|
|
|
calchandlesNurb(nu);
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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
|
|
|
}
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
cut= a;
|
|
|
|
nu1= nu;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(nu->pntsv==1) {
|
|
|
|
bp= nu->bp;
|
|
|
|
for(a=0; a<nu->pntsu-1; a++) {
|
|
|
|
if( bp->f1 & SELECT ) {
|
|
|
|
bp1= bp;
|
|
|
|
bp2= bp+1;
|
|
|
|
if( bp2->f1 & 1 ) ;
|
|
|
|
else { /* maybe do not make cyclic */
|
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
|
|
|
if(a==0 && (nu->flagu & CU_NURB_CYCLIC) ) {
|
2009-01-14 12:26:45 +00:00
|
|
|
bp2= bp+(nu->pntsu-1);
|
|
|
|
if( bp2->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;
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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
|
|
|
}
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
cut= a;
|
|
|
|
nu1= nu;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(nu1) break;
|
|
|
|
}
|
|
|
|
if(nu1) {
|
|
|
|
if(bezt1) {
|
|
|
|
if(nu1->pntsu==2) { /* remove completely */
|
2010-07-25 11:57:36 +00:00
|
|
|
BLI_remlink(nubase, nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
freeNurb(nu); nu = NULL;
|
|
|
|
}
|
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
|
|
|
else if(nu1->flagu & CU_NURB_CYCLIC) { /* cyclic */
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt =
|
|
|
|
(BezTriple*)MEM_mallocN((cut+1) * sizeof(BezTriple), "delNurb1");
|
2010-07-25 11:57:36 +00:00
|
|
|
ED_curve_beztcpy(editnurb, bezt, nu1->bezt, cut+1);
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu1->pntsu-cut-1;
|
2010-07-25 11:57:36 +00:00
|
|
|
ED_curve_beztcpy(editnurb, nu1->bezt, bezt2, a);
|
|
|
|
ED_curve_beztcpy(editnurb, nu1->bezt+a, bezt, cut+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
|
|
|
nu1->flagu &= ~CU_NURB_CYCLIC;
|
2009-01-14 12:26:45 +00:00
|
|
|
MEM_freeN(bezt);
|
|
|
|
calchandlesNurb(nu);
|
|
|
|
}
|
|
|
|
else { /* add new curve */
|
|
|
|
|
|
|
|
/* seems to be an error here... but where? (a can become zero) */
|
|
|
|
|
|
|
|
nu =
|
|
|
|
(Nurb*)MEM_mallocN(sizeof(Nurb), "delNurb2");
|
|
|
|
memcpy(nu, nu1, sizeof(Nurb));
|
2010-07-25 11:57:36 +00:00
|
|
|
BLI_addtail(nubase, nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
nu->bezt =
|
|
|
|
(BezTriple*)MEM_mallocN((cut+1) * sizeof(BezTriple), "delNurb3");
|
2010-07-25 11:57:36 +00:00
|
|
|
ED_curve_beztcpy(editnurb, nu->bezt, nu1->bezt, cut+1);
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu1->pntsu-cut-1;
|
|
|
|
|
|
|
|
bezt =
|
|
|
|
(BezTriple*)MEM_mallocN(a * sizeof(BezTriple), "delNurb4");
|
2010-07-25 11:57:36 +00:00
|
|
|
ED_curve_beztcpy(editnurb, bezt, nu1->bezt+cut+1, a);
|
2009-01-14 12:26:45 +00:00
|
|
|
MEM_freeN(nu1->bezt);
|
|
|
|
nu1->bezt= bezt;
|
|
|
|
nu1->pntsu= a;
|
|
|
|
nu->pntsu= cut+1;
|
|
|
|
|
|
|
|
|
|
|
|
calchandlesNurb(nu);
|
|
|
|
calchandlesNurb(nu1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(bp1) {
|
|
|
|
if(nu1->pntsu==2) { /* remove completely */
|
2010-07-25 11:57:36 +00:00
|
|
|
BLI_remlink(nubase, nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
freeNurb(nu); nu= NULL;
|
|
|
|
}
|
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
|
|
|
else if(nu1->flagu & CU_NURB_CYCLIC) { /* cyclic */
|
2009-01-14 12:26:45 +00:00
|
|
|
bp =
|
|
|
|
(BPoint*)MEM_mallocN((cut+1) * sizeof(BPoint), "delNurb5");
|
2010-07-25 11:57:36 +00:00
|
|
|
ED_curve_bpcpy(editnurb, bp, nu1->bp, cut+1);
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu1->pntsu-cut-1;
|
2010-07-25 11:57:36 +00:00
|
|
|
ED_curve_bpcpy(editnurb, nu1->bp, bp2, a);
|
|
|
|
ED_curve_bpcpy(editnurb, nu1->bp+a, bp, cut+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
|
|
|
nu1->flagu &= ~CU_NURB_CYCLIC;
|
2009-01-14 12:26:45 +00:00
|
|
|
MEM_freeN(bp);
|
|
|
|
}
|
|
|
|
else { /* add new curve */
|
|
|
|
nu = (Nurb*)MEM_mallocN(sizeof(Nurb), "delNurb6");
|
|
|
|
memcpy(nu, nu1, sizeof(Nurb));
|
2010-07-25 11:57:36 +00:00
|
|
|
BLI_addtail(nubase, nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
nu->bp =
|
|
|
|
(BPoint*)MEM_mallocN((cut+1) * sizeof(BPoint), "delNurb7");
|
2010-07-25 11:57:36 +00:00
|
|
|
ED_curve_bpcpy(editnurb, nu->bp, nu1->bp, cut+1);
|
2009-01-14 12:26:45 +00:00
|
|
|
a= nu1->pntsu-cut-1;
|
|
|
|
bp =
|
|
|
|
(BPoint*)MEM_mallocN(a * sizeof(BPoint), "delNurb8");
|
2010-07-25 11:57:36 +00:00
|
|
|
ED_curve_bpcpy(editnurb, bp, nu1->bp+cut+1, a);
|
2009-01-14 12:26:45 +00:00
|
|
|
MEM_freeN(nu1->bp);
|
|
|
|
nu1->bp= bp;
|
|
|
|
nu1->pntsu= a;
|
|
|
|
nu->pntsu= cut+1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-07-25 11:57:36 +00:00
|
|
|
else if(type==2) {
|
|
|
|
keyIndex_delNurbList(editnurb, nubase);
|
|
|
|
freeNurblist(nubase);
|
|
|
|
}
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-12-20 19:47:16 +00:00
|
|
|
if(ED_curve_updateAnimPaths(obedit))
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, obedit);
|
2010-12-06 17:20:22 +00:00
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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
|
|
|
}
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int delete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-04-22 18:39:44 +00:00
|
|
|
uiPopupMenu *pup;
|
|
|
|
uiLayout *layout;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
if(obedit->type==OB_SURF) {
|
use ICON_NULL define rather then 0, makes UI calls less confusing. (no functional change)
eg: uiItemR(row, &dvar_ptr, "type", 0, "", 0); -> uiItemR(row, &dvar_ptr, "type", 0, "", ICON_NULL);
2010-12-23 02:43:40 +00:00
|
|
|
pup= uiPupMenuBegin(C, "Delete", ICON_NULL);
|
2009-04-22 18:39:44 +00:00
|
|
|
layout= uiPupMenuLayout(pup);
|
2010-03-23 15:25:33 +00:00
|
|
|
uiItemEnumO(layout, op->type->idname, NULL, 0, "type", 0);
|
|
|
|
uiItemEnumO(layout, op->type->idname, NULL, 0, "type", 2);
|
2009-04-22 18:39:44 +00:00
|
|
|
uiPupMenuEnd(C, pup);
|
2009-02-11 23:02:21 +00:00
|
|
|
}
|
|
|
|
else {
|
use ICON_NULL define rather then 0, makes UI calls less confusing. (no functional change)
eg: uiItemR(row, &dvar_ptr, "type", 0, "", 0); -> uiItemR(row, &dvar_ptr, "type", 0, "", ICON_NULL);
2010-12-23 02:43:40 +00:00
|
|
|
pup= uiPupMenuBegin(C, "Delete", ICON_NULL);
|
2009-04-22 18:39:44 +00:00
|
|
|
layout= uiPupMenuLayout(pup);
|
|
|
|
uiItemsEnumO(layout, op->type->idname, "type");
|
|
|
|
uiPupMenuEnd(C, pup);
|
2009-02-11 23:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CURVE_OT_delete(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
static EnumPropertyItem type_items[] = {
|
2010-07-15 16:56:04 +00:00
|
|
|
{0, "SELECTED", 0, "Select", ""},
|
2009-06-16 00:52:21 +00:00
|
|
|
{1, "SEGMENT", 0, "Segment", ""},
|
|
|
|
{2, "ALL", 0, "All", ""},
|
|
|
|
{0, NULL, 0, NULL, NULL}};
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Delete";
|
|
|
|
ot->idname= "CURVE_OT_delete";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= delete_exec;
|
|
|
|
ot->invoke= delete_invoke;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
/* properties */
|
|
|
|
RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "Which elements to delete.");
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
2009-07-21 00:36:07 +00:00
|
|
|
int clear= (strcmp(op->idname, "CURVE_OT_shade_flat") == 0);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-02-11 23:02:21 +00:00
|
|
|
if(obedit->type != OB_CURVE)
|
|
|
|
return OPERATOR_CANCELLED;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
if(isNurbsel(nu)) {
|
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
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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 */
|
2009-07-21 00:36:07 +00:00
|
|
|
ot->name= "Shade Smooth";
|
|
|
|
ot->idname= "CURVE_OT_shade_smooth";
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
2009-07-21 00:36:07 +00:00
|
|
|
ot->exec= shade_smooth_exec;
|
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
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
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 */
|
|
|
|
ot->name= "Shade Flat";
|
|
|
|
ot->idname= "CURVE_OT_shade_flat";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= shade_smooth_exec;
|
|
|
|
ot->poll= ED_operator_editsurfcurve;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
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? ****************/
|
2009-02-11 23:02:21 +00:00
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
int join_curve_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2010-08-01 12:47:49 +00:00
|
|
|
Main *bmain= CTX_data_main(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
|
|
|
Scene *scene= CTX_data_scene(C);
|
2009-07-13 00:40:20 +00:00
|
|
|
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;
|
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-01-14 12:26:45 +00:00
|
|
|
tempbase.first= tempbase.last= 0;
|
|
|
|
|
|
|
|
/* 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
|
|
|
|
2009-07-13 00:40:20 +00:00
|
|
|
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
|
|
|
|
if(base->object->type==ob->type) {
|
|
|
|
if(base->object != ob) {
|
|
|
|
|
|
|
|
cu= base->object->data;
|
|
|
|
|
|
|
|
if(cu->nurb.first) {
|
|
|
|
/* watch it: switch order here really goes wrong */
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_m4_m4m4(cmat, base->object->obmat, imat);
|
2009-07-13 00:40:20 +00:00
|
|
|
|
|
|
|
nu= cu->nurb.first;
|
|
|
|
while(nu) {
|
|
|
|
newnu= duplicateNurb(nu);
|
2010-09-10 06:05:18 +00:00
|
|
|
if(ob->totcol) { /* TODO, merge material lists */
|
|
|
|
CLAMP(newnu->mat_nr, 0, ob->totcol-1);
|
|
|
|
} 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
|
|
|
|
2009-07-13 00:40:20 +00:00
|
|
|
if( (bezt= newnu->bezt) ) {
|
|
|
|
a= newnu->pntsu;
|
|
|
|
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
|
|
|
}
|
2009-07-13 00:40:20 +00:00
|
|
|
}
|
|
|
|
if( (bp= newnu->bp) ) {
|
|
|
|
a= newnu->pntsu*nu->pntsv;
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
2009-07-13 00:40:20 +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
|
|
|
|
|
|
|
cu= ob->data;
|
2010-12-21 14:49:34 +00:00
|
|
|
BLI_movelisttolist(&cu->nurb, &tempbase);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-08-01 12:47:49 +00:00
|
|
|
DAG_scene_sort(bmain, scene); // because we removed object(s), call before editmode!
|
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
|
|
|
ED_object_enter_editmode(C, EM_WAITCURSOR);
|
- add torus back from 2.4x as an operator
bpy.ops.mesh.primitive_torus_add(major_radius=1, minor_radius=0.25, major_segments=48, minor_segments=16)
- experemental dynamic menus, used for INFO_MT_file, INFO_MT_file_import, INFO_MT_file_export and INFO_MT_mesh_add. these can have items added from python.
eg.
- removed OBJECT_OT_mesh_add, use the python add menu instead.
- made mesh primitive ops - MESH_OT_primitive_plane_add, ...cube_add, etc. work in object mode.
- RNA scene.active_object wrapped
- bugfix [#19466] 2.5: Tweak menu only available for mesh objects added within Edit Mode
ED_object_exit_editmode was always doing an undo push, made this optional using the existing flag - EM_DO_UNDO, called everywhere except when adding primitives.
2009-10-10 21:23:20 +00:00
|
|
|
ED_object_exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR|EM_DO_UNDO);
|
2009-07-13 00:40:20 +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-13 17:37:01 +00:00
|
|
|
/************ add primitive, used by object/ module ****************/
|
2010-11-23 17:28:41 +00:00
|
|
|
|
2010-12-03 17:05:21 +00:00
|
|
|
static const char *get_curve_defname(int type)
|
2010-11-23 17:28:41 +00:00
|
|
|
{
|
|
|
|
int stype= type & CU_PRIMITIVE;
|
|
|
|
|
|
|
|
if((type & CU_TYPE)==CU_BEZIER) {
|
|
|
|
switch (stype) {
|
|
|
|
case CU_PRIM_CURVE: return "BezierCurve";
|
|
|
|
case CU_PRIM_CIRCLE: return "BezierCircle";
|
|
|
|
case CU_PRIM_PATH: return "CurvePath";
|
|
|
|
default:
|
|
|
|
return "Curve";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
switch (stype) {
|
|
|
|
case CU_PRIM_CURVE: return "NurbsCurve";
|
|
|
|
case CU_PRIM_CIRCLE: return "NurbsCircle";
|
|
|
|
case CU_PRIM_PATH: return "NurbsPath";
|
|
|
|
default:
|
|
|
|
return "Curve";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-03 17:05:21 +00:00
|
|
|
static const char *get_surf_defname(int type)
|
2010-11-23 17:28:41 +00:00
|
|
|
{
|
|
|
|
int stype= type & CU_PRIMITIVE;
|
|
|
|
|
|
|
|
switch (stype) {
|
|
|
|
case CU_PRIM_CURVE: return "SurfCurve";
|
|
|
|
case CU_PRIM_CIRCLE: return "SurfCircle";
|
|
|
|
case CU_PRIM_PATCH: return "SurfPatch";
|
|
|
|
case CU_PRIM_SPHERE: return "SurfSphere";
|
|
|
|
case CU_PRIM_DONUT: return "SurfTorus";
|
|
|
|
default:
|
|
|
|
return "Surface";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Nurb *add_nurbs_primitive(bContext *C, float mat[4][4], int type, int newob)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2009-01-26 15:23:29 +00:00
|
|
|
static int xzproj= 0; /* this function calls itself... */
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
2009-01-26 15:23:29 +00:00
|
|
|
View3D *v3d= CTX_wm_view3d(C);
|
2010-09-30 05:26:36 +00:00
|
|
|
RegionView3D *rv3d= ED_view3d_context_rv3d(C);
|
2009-01-14 12:26:45 +00:00
|
|
|
Nurb *nu = NULL;
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
2010-10-16 10:14:17 +00:00
|
|
|
Curve *cu= (Curve*)obedit->data;
|
2011-01-03 10:47:36 +00:00
|
|
|
float vec[3], zvec[3]= {0.0f, 0.0f, 1.0f};
|
|
|
|
float umat[4][4]= MAT4_UNITY, viewmat[4][4]= MAT4_UNITY;
|
2010-01-12 01:50:34 +00:00
|
|
|
float fac, grid;
|
2009-01-26 15:23:29 +00:00
|
|
|
int a, b, cutype, stype;
|
2009-09-12 18:09:59 +00:00
|
|
|
int force_3d = ((Curve *)obedit->data)->flag & CU_3D; /* could be adding to an existing 3D curve */
|
2010-09-30 05:26:36 +00:00
|
|
|
|
2011-01-03 10:47:36 +00:00
|
|
|
if(rv3d) {
|
|
|
|
copy_m4_m4(viewmat, rv3d->viewmat);
|
|
|
|
VECCOPY(zvec, rv3d->viewinv[2]);
|
|
|
|
}
|
|
|
|
|
2009-01-26 15:23:29 +00:00
|
|
|
cutype= type & CU_TYPE; // poly, bezier, nurbs, etc
|
|
|
|
stype= type & CU_PRIMITIVE;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
if (v3d) grid = v3d->grid;
|
|
|
|
else grid = 1.0;
|
|
|
|
|
2010-01-12 01:50:34 +00:00
|
|
|
setflagsNurb(editnurb, 0);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-01-26 15:23:29 +00:00
|
|
|
/* these types call this function to return a Nurb */
|
|
|
|
if (stype!=CU_PRIM_TUBE && stype!=CU_PRIM_DONUT) {
|
2009-01-14 12:26:45 +00:00
|
|
|
nu = (Nurb*)MEM_callocN(sizeof(Nurb), "addNurbprim");
|
2009-09-08 00:23:33 +00:00
|
|
|
nu->type= cutype;
|
2010-10-16 10:14:17 +00:00
|
|
|
nu->resolu= cu->resolu;
|
|
|
|
nu->resolv= cu->resolv;
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch(stype) {
|
2009-01-26 15:23:29 +00:00
|
|
|
case CU_PRIM_CURVE: /* curve */
|
2010-10-16 10:14:17 +00:00
|
|
|
nu->resolu= cu->resolu;
|
2009-01-26 15:23:29 +00:00
|
|
|
if(cutype==CU_BEZIER) {
|
2009-09-12 18:09:59 +00:00
|
|
|
if (!force_3d) nu->flag |= CU_2D;
|
2009-01-14 12:26:45 +00:00
|
|
|
nu->pntsu= 2;
|
|
|
|
nu->bezt =
|
|
|
|
(BezTriple*)MEM_callocN(2 * sizeof(BezTriple), "addNurbprim1");
|
|
|
|
bezt= nu->bezt;
|
|
|
|
bezt->h1= bezt->h2= HD_ALIGN;
|
|
|
|
bezt->f1= bezt->f2= bezt->f3= SELECT;
|
|
|
|
bezt->radius = 1.0;
|
|
|
|
|
|
|
|
bezt->vec[1][0]+= -grid;
|
|
|
|
bezt->vec[0][0]+= -1.5*grid;
|
|
|
|
bezt->vec[0][1]+= -0.5*grid;
|
|
|
|
bezt->vec[2][0]+= -0.5*grid;
|
|
|
|
bezt->vec[2][1]+= 0.5*grid;
|
2010-01-12 01:50:34 +00:00
|
|
|
for(a=0;a<3;a++) mul_m4_v3(mat, bezt->vec[a]);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
bezt++;
|
|
|
|
bezt->h1= bezt->h2= HD_ALIGN;
|
|
|
|
bezt->f1= bezt->f2= bezt->f3= SELECT;
|
|
|
|
bezt->radius = bezt->weight = 1.0;
|
|
|
|
|
2010-01-12 01:50:34 +00:00
|
|
|
bezt->vec[0][0] = 0;
|
|
|
|
bezt->vec[0][1] = 0;
|
|
|
|
bezt->vec[1][0] = grid;
|
|
|
|
bezt->vec[1][1] = 0;
|
|
|
|
bezt->vec[2][0] = grid*2;
|
|
|
|
bezt->vec[2][1] = 0;
|
|
|
|
for(a=0;a<3;a++) mul_m4_v3(mat, bezt->vec[a]);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
calchandlesNurb(nu);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
nu->pntsu= 4;
|
|
|
|
nu->pntsv= 1;
|
|
|
|
nu->orderu= 4;
|
|
|
|
nu->bp= callocstructN(BPoint, 4, "addNurbprim3");
|
|
|
|
|
|
|
|
bp= nu->bp;
|
|
|
|
for(a=0;a<4;a++, bp++) {
|
|
|
|
bp->vec[3]= 1.0;
|
|
|
|
bp->f1= SELECT;
|
|
|
|
bp->radius = bp->weight = 1.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bp= nu->bp;
|
|
|
|
bp->vec[0]+= -1.5*grid;
|
|
|
|
bp++;
|
|
|
|
bp->vec[0]+= -grid;
|
|
|
|
bp->vec[1]+= grid;
|
|
|
|
bp++;
|
|
|
|
bp->vec[0]+= grid;
|
|
|
|
bp->vec[1]+= grid;
|
|
|
|
bp++;
|
|
|
|
bp->vec[0]+= 1.5*grid;
|
|
|
|
|
|
|
|
bp= nu->bp;
|
2010-01-12 01:50:34 +00:00
|
|
|
for(a=0;a<4;a++, bp++) mul_m4_v3(mat,bp->vec);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-01-26 15:23:29 +00:00
|
|
|
if(cutype==CU_NURBS) {
|
2010-09-30 06:51:32 +00:00
|
|
|
nu->knotsu= NULL; /* nurbs_knot_calc_u allocates */
|
|
|
|
nurbs_knot_calc_u(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
2009-01-26 15:23:29 +00:00
|
|
|
case CU_PRIM_PATH: /* 5 point path */
|
2009-01-14 12:26:45 +00:00
|
|
|
nu->pntsu= 5;
|
|
|
|
nu->pntsv= 1;
|
|
|
|
nu->orderu= 5;
|
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_ENDPOINT; /* endpoint */
|
2010-10-16 10:14:17 +00:00
|
|
|
nu->resolu= cu->resolu;
|
2009-01-14 12:26:45 +00:00
|
|
|
nu->bp= callocstructN(BPoint, 5, "addNurbprim3");
|
|
|
|
|
|
|
|
bp= nu->bp;
|
|
|
|
for(a=0;a<5;a++, bp++) {
|
|
|
|
bp->vec[3]= 1.0;
|
|
|
|
bp->f1= SELECT;
|
|
|
|
bp->radius = bp->weight = 1.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bp= nu->bp;
|
|
|
|
bp->vec[0]+= -2.0*grid;
|
|
|
|
bp++;
|
|
|
|
bp->vec[0]+= -grid;
|
|
|
|
bp++; bp++;
|
|
|
|
bp->vec[0]+= grid;
|
|
|
|
bp++;
|
|
|
|
bp->vec[0]+= 2.0*grid;
|
|
|
|
|
|
|
|
bp= nu->bp;
|
2010-01-12 01:50:34 +00:00
|
|
|
for(a=0;a<5;a++, bp++) mul_m4_v3(mat,bp->vec);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2009-01-26 15:23:29 +00:00
|
|
|
if(cutype==CU_NURBS) {
|
2010-09-30 06:51:32 +00:00
|
|
|
nu->knotsu= NULL; /* nurbs_knot_calc_u allocates */
|
|
|
|
nurbs_knot_calc_u(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
2009-01-26 15:23:29 +00:00
|
|
|
case CU_PRIM_CIRCLE: /* circle */
|
2010-10-16 10:14:17 +00:00
|
|
|
nu->resolu= cu->resolu;
|
2010-11-23 17:28:41 +00:00
|
|
|
|
2009-01-26 15:23:29 +00:00
|
|
|
if(cutype==CU_BEZIER) {
|
2009-09-12 18:09:59 +00:00
|
|
|
if (!force_3d) nu->flag |= CU_2D;
|
2009-01-14 12:26:45 +00:00
|
|
|
nu->pntsu= 4;
|
|
|
|
nu->bezt= callocstructN(BezTriple, 4, "addNurbprim1");
|
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
|
|
|
bezt= nu->bezt;
|
|
|
|
|
|
|
|
bezt->h1= bezt->h2= HD_AUTO;
|
|
|
|
bezt->f1= bezt->f2= bezt->f3= SELECT;
|
|
|
|
bezt->vec[1][0]+= -grid;
|
2010-01-12 01:50:34 +00:00
|
|
|
for(a=0;a<3;a++) mul_m4_v3(mat,bezt->vec[a]);
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt->radius = bezt->weight = 1.0;
|
|
|
|
|
|
|
|
bezt++;
|
|
|
|
bezt->h1= bezt->h2= HD_AUTO;
|
|
|
|
bezt->f1= bezt->f2= bezt->f3= SELECT;
|
|
|
|
bezt->vec[1][1]+= grid;
|
2010-01-12 01:50:34 +00:00
|
|
|
for(a=0;a<3;a++) mul_m4_v3(mat,bezt->vec[a]);
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt->radius = bezt->weight = 1.0;
|
|
|
|
|
|
|
|
bezt++;
|
|
|
|
bezt->h1= bezt->h2= HD_AUTO;
|
|
|
|
bezt->f1= bezt->f2= bezt->f3= SELECT;
|
|
|
|
bezt->vec[1][0]+= grid;
|
2010-01-12 01:50:34 +00:00
|
|
|
for(a=0;a<3;a++) mul_m4_v3(mat,bezt->vec[a]);
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt->radius = bezt->weight = 1.0;
|
|
|
|
|
|
|
|
bezt++;
|
|
|
|
bezt->h1= bezt->h2= HD_AUTO;
|
|
|
|
bezt->f1= bezt->f2= bezt->f3= SELECT;
|
|
|
|
bezt->vec[1][1]+= -grid;
|
2010-01-12 01:50:34 +00:00
|
|
|
for(a=0;a<3;a++) mul_m4_v3(mat,bezt->vec[a]);
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt->radius = bezt->weight = 1.0;
|
|
|
|
|
|
|
|
calchandlesNurb(nu);
|
|
|
|
}
|
2009-01-26 15:23:29 +00:00
|
|
|
else if( cutype==CU_NURBS ) { /* nurb */
|
2009-01-14 12:26:45 +00:00
|
|
|
nu->pntsu= 8;
|
|
|
|
nu->pntsv= 1;
|
|
|
|
nu->orderu= 4;
|
|
|
|
nu->bp= callocstructN(BPoint, 8, "addNurbprim6");
|
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
|
|
|
bp= nu->bp;
|
|
|
|
|
|
|
|
for(a=0; a<8; a++) {
|
|
|
|
bp->f1= SELECT;
|
|
|
|
if(xzproj==0) {
|
|
|
|
bp->vec[0]+= nurbcircle[a][0]*grid;
|
|
|
|
bp->vec[1]+= nurbcircle[a][1]*grid;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp->vec[0]+= 0.25*nurbcircle[a][0]*grid-.75*grid;
|
|
|
|
bp->vec[2]+= 0.25*nurbcircle[a][1]*grid;
|
|
|
|
}
|
2010-09-30 05:26:36 +00:00
|
|
|
if(a & 1) bp->vec[3]= 0.25*M_SQRT2;
|
2009-01-14 12:26:45 +00:00
|
|
|
else bp->vec[3]= 1.0;
|
2010-01-12 01:50:34 +00:00
|
|
|
mul_m4_v3(mat,bp->vec);
|
2009-01-14 12:26:45 +00:00
|
|
|
bp->radius = bp->weight = 1.0;
|
|
|
|
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
break;
|
2009-01-26 15:23:29 +00:00
|
|
|
case CU_PRIM_PATCH: /* 4x4 patch */
|
|
|
|
if( cutype==CU_NURBS ) { /* nurb */
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
nu->pntsu= 4;
|
|
|
|
nu->pntsv= 4;
|
|
|
|
nu->orderu= 4;
|
|
|
|
nu->orderv= 4;
|
|
|
|
nu->flag= CU_SMOOTH;
|
|
|
|
nu->bp= callocstructN(BPoint, 4*4, "addNurbprim6");
|
|
|
|
nu->flagu= 0;
|
|
|
|
nu->flagv= 0;
|
|
|
|
bp= nu->bp;
|
|
|
|
|
|
|
|
for(a=0; a<4; a++) {
|
|
|
|
for(b=0; b<4; b++) {
|
|
|
|
bp->f1= SELECT;
|
|
|
|
fac= (float)a -1.5;
|
|
|
|
bp->vec[0]+= fac*grid;
|
|
|
|
fac= (float)b -1.5;
|
|
|
|
bp->vec[1]+= fac*grid;
|
|
|
|
if(a==1 || a==2) if(b==1 || b==2) {
|
|
|
|
bp->vec[2]+= grid;
|
|
|
|
}
|
2010-01-12 01:50:34 +00:00
|
|
|
mul_m4_v3(mat,bp->vec);
|
2009-01-14 12:26:45 +00:00
|
|
|
bp->vec[3]= 1.0;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(nu);
|
|
|
|
nurbs_knot_calc_v(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
break;
|
2010-09-01 21:11:33 +00:00
|
|
|
case CU_PRIM_TUBE: /* Cylinder */
|
2009-01-26 15:23:29 +00:00
|
|
|
if( cutype==CU_NURBS ) {
|
2010-01-12 01:50:34 +00:00
|
|
|
nu= add_nurbs_primitive(C, mat, CU_NURBS|CU_PRIM_CIRCLE, 0); /* circle */
|
2010-10-16 10:14:17 +00:00
|
|
|
nu->resolu= cu->resolu;
|
2009-01-14 12:26:45 +00:00
|
|
|
nu->flag= CU_SMOOTH;
|
|
|
|
BLI_addtail(editnurb, nu); /* temporal for extrude and translate */
|
|
|
|
vec[0]=vec[1]= 0.0;
|
|
|
|
vec[2]= -grid;
|
2010-09-29 15:19:16 +00:00
|
|
|
|
2010-11-23 17:28:41 +00:00
|
|
|
if(newob && (U.flag & USER_ADD_VIEWALIGNED) == 0) {
|
2010-09-29 15:19:16 +00:00
|
|
|
/* pass */
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mul_mat3_m4_v3(mat, vec);
|
|
|
|
}
|
2010-01-12 01:50:34 +00:00
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
translateflagNurb(editnurb, 1, vec);
|
2010-07-25 11:57:36 +00:00
|
|
|
extrudeflagNurb(cu->editnurb, 1);
|
2009-01-14 12:26:45 +00:00
|
|
|
vec[0]= -2*vec[0];
|
|
|
|
vec[1]= -2*vec[1];
|
|
|
|
vec[2]= -2*vec[2];
|
|
|
|
translateflagNurb(editnurb, 1, vec);
|
|
|
|
|
|
|
|
BLI_remlink(editnurb, nu);
|
|
|
|
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a-- >0) {
|
|
|
|
bp->f1 |= SELECT;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2009-01-26 15:23:29 +00:00
|
|
|
case CU_PRIM_SPHERE: /* sphere */
|
|
|
|
if( cutype==CU_NURBS ) {
|
2010-01-12 01:50:34 +00:00
|
|
|
float tmp_cent[3] = {0.f, 0.f, 0.f};
|
2010-09-30 05:26:36 +00:00
|
|
|
float tmp_vec[3] = {0.f, 0.f, 1.f};
|
2010-01-12 01:50:34 +00:00
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
nu->pntsu= 5;
|
|
|
|
nu->pntsv= 1;
|
|
|
|
nu->orderu= 3;
|
2010-10-16 10:14:17 +00:00
|
|
|
nu->resolu= cu->resolu;
|
|
|
|
nu->resolv= cu->resolv;
|
2009-01-14 12:26:45 +00:00
|
|
|
nu->flag= CU_SMOOTH;
|
|
|
|
nu->bp= callocstructN(BPoint, 5, "addNurbprim6");
|
|
|
|
nu->flagu= 0;
|
|
|
|
bp= nu->bp;
|
|
|
|
|
|
|
|
for(a=0; a<5; a++) {
|
|
|
|
bp->f1= SELECT;
|
|
|
|
bp->vec[0]+= nurbcircle[a][0]*grid;
|
|
|
|
bp->vec[2]+= nurbcircle[a][1]*grid;
|
2010-09-30 05:26:36 +00:00
|
|
|
if(a & 1) bp->vec[3]= 0.5*M_SQRT2;
|
2009-01-14 12:26:45 +00:00
|
|
|
else bp->vec[3]= 1.0;
|
2010-01-12 01:50:34 +00:00
|
|
|
mul_m4_v3(mat,bp->vec);
|
2009-01-14 12:26:45 +00:00
|
|
|
bp++;
|
|
|
|
}
|
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_BEZIER;
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_u(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
BLI_addtail(editnurb, nu); /* temporal for spin */
|
2010-09-30 05:26:36 +00:00
|
|
|
|
2010-11-23 17:28:41 +00:00
|
|
|
if(newob && (U.flag & USER_ADD_VIEWALIGNED) == 0) spin_nurb(umat, obedit, tmp_vec, tmp_cent);
|
2011-01-03 10:47:36 +00:00
|
|
|
else if ((U.flag & USER_ADD_VIEWALIGNED)) spin_nurb(viewmat, obedit, zvec, mat[3]);
|
2010-09-30 05:26:36 +00:00
|
|
|
else spin_nurb(umat, obedit, tmp_vec, mat[3]);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-09-30 06:51:32 +00:00
|
|
|
nurbs_knot_calc_v(nu);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a-- >0) {
|
|
|
|
bp->f1 |= SELECT;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
BLI_remlink(editnurb, nu);
|
|
|
|
}
|
|
|
|
break;
|
2010-09-01 20:18:31 +00:00
|
|
|
case CU_PRIM_DONUT: /* torus */
|
2009-01-26 15:23:29 +00:00
|
|
|
if( cutype==CU_NURBS ) {
|
2010-01-12 01:50:34 +00:00
|
|
|
float tmp_cent[3] = {0.f, 0.f, 0.f};
|
2010-09-30 05:26:36 +00:00
|
|
|
float tmp_vec[3] = {0.f, 0.f, 1.f};
|
2010-01-12 01:50:34 +00:00
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
xzproj= 1;
|
2010-01-12 01:50:34 +00:00
|
|
|
nu= add_nurbs_primitive(C, mat, CU_NURBS|CU_PRIM_CIRCLE, 0); /* circle */
|
2009-01-14 12:26:45 +00:00
|
|
|
xzproj= 0;
|
2010-10-16 10:14:17 +00:00
|
|
|
nu->resolu= cu->resolu;
|
|
|
|
nu->resolv= cu->resolv;
|
2009-01-14 12:26:45 +00:00
|
|
|
nu->flag= CU_SMOOTH;
|
2010-09-30 05:26:36 +00:00
|
|
|
BLI_addtail(editnurb, nu); /* temporal for spin */
|
|
|
|
|
|
|
|
/* same as above */
|
2010-11-23 17:28:41 +00:00
|
|
|
if(newob && (U.flag & USER_ADD_VIEWALIGNED) == 0) spin_nurb(umat, obedit, tmp_vec, tmp_cent);
|
2011-01-03 10:47:36 +00:00
|
|
|
else if ((U.flag & USER_ADD_VIEWALIGNED)) spin_nurb(viewmat, obedit, zvec, mat[3]);
|
2010-09-30 05:26:36 +00:00
|
|
|
else spin_nurb(umat, obedit, tmp_vec, mat[3]);
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
BLI_remlink(editnurb, nu);
|
|
|
|
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
bp= nu->bp;
|
|
|
|
while(a-- >0) {
|
|
|
|
bp->f1 |= SELECT;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* always do: */
|
2009-09-08 00:23:33 +00:00
|
|
|
nu->flag |= CU_SMOOTH;
|
2009-01-14 12:26:45 +00:00
|
|
|
|
|
|
|
test2DNurb(nu);
|
|
|
|
|
|
|
|
return nu;
|
|
|
|
}
|
2010-05-24 07:14:55 +00:00
|
|
|
|
2010-06-22 21:11:13 +00:00
|
|
|
static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) {
|
2010-05-23 02:02:04 +00:00
|
|
|
|
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
|
|
|
ListBase *editnurb;
|
|
|
|
Nurb *nu;
|
2010-06-22 21:11:13 +00:00
|
|
|
int newob= 0;
|
2010-05-23 02:02:04 +00:00
|
|
|
int enter_editmode;
|
|
|
|
unsigned int layer;
|
|
|
|
float loc[3], rot[3];
|
|
|
|
float mat[4][4];
|
2010-06-22 21:11:13 +00:00
|
|
|
|
2010-06-14 15:39:50 +00:00
|
|
|
if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
2010-06-22 21:11:13 +00:00
|
|
|
if (!isSurf) { /* adding curve */
|
|
|
|
if(obedit==NULL || obedit->type!=OB_CURVE) {
|
|
|
|
Curve *cu;
|
2010-11-23 17:28:41 +00:00
|
|
|
|
2010-06-22 21:11:13 +00:00
|
|
|
obedit= ED_object_add_type(C, OB_CURVE, loc, rot, TRUE, layer);
|
|
|
|
newob = 1;
|
|
|
|
|
|
|
|
cu= (Curve*)obedit->data;
|
|
|
|
cu->flag |= CU_DEFORM_FILL;
|
2010-11-23 17:28:41 +00:00
|
|
|
|
2010-06-22 21:11:13 +00:00
|
|
|
if(type & CU_PRIM_PATH)
|
|
|
|
cu->flag |= CU_PATH|CU_3D;
|
2010-11-23 17:28:41 +00:00
|
|
|
}
|
2010-12-05 18:59:23 +00:00
|
|
|
else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
|
2010-11-23 17:28:41 +00:00
|
|
|
}
|
|
|
|
else { /* adding surface */
|
2010-06-22 21:11:13 +00:00
|
|
|
if(obedit==NULL || obedit->type!=OB_SURF) {
|
|
|
|
obedit= ED_object_add_type(C, OB_SURF, loc, rot, TRUE, layer);
|
|
|
|
newob = 1;
|
2010-11-23 17:28:41 +00:00
|
|
|
}
|
2010-12-05 18:59:23 +00:00
|
|
|
else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
|
2010-06-13 05:48:21 +00:00
|
|
|
}
|
2010-06-22 21:11:13 +00:00
|
|
|
|
2010-11-23 17:28:41 +00:00
|
|
|
/* rename here, the undo stack checks name for valid undo pushes */
|
|
|
|
if(newob) {
|
|
|
|
|
|
|
|
if(obedit->type==OB_CURVE) {
|
|
|
|
rename_id((ID *)obedit, get_curve_defname(type));
|
|
|
|
rename_id((ID *)obedit->data, get_curve_defname(type));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rename_id((ID *)obedit, get_surf_defname(type));
|
|
|
|
rename_id((ID *)obedit->data, get_surf_defname(type));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ED_object_add_type doesnt do an undo, is needed for redo operator on primitive */
|
|
|
|
if(newob && enter_editmode)
|
|
|
|
ED_undo_push(C, "Enter Editmode");
|
|
|
|
|
2010-06-09 19:20:05 +00:00
|
|
|
ED_object_new_primitive_matrix(C, obedit, loc, rot, mat);
|
2010-06-22 21:11:13 +00:00
|
|
|
|
2010-05-23 02:02:04 +00:00
|
|
|
nu= add_nurbs_primitive(C, mat, type, newob);
|
|
|
|
editnurb= curve_get_editcurve(obedit);
|
|
|
|
BLI_addtail(editnurb, nu);
|
2010-06-22 21:11:13 +00:00
|
|
|
|
2010-05-23 02:02:04 +00:00
|
|
|
/* userdef */
|
|
|
|
if (newob && !enter_editmode) {
|
|
|
|
ED_object_exit_editmode(C, EM_FREEDATA);
|
|
|
|
}
|
2010-06-22 21:11:13 +00:00
|
|
|
|
2010-05-23 02:02:04 +00:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit);
|
2010-06-22 21:11:13 +00:00
|
|
|
|
2010-05-23 02:02:04 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
2010-06-22 21:11:13 +00:00
|
|
|
|
|
|
|
static int curve_prim_add(bContext *C, wmOperator *op, int type) {
|
|
|
|
return curvesurf_prim_add(C, op, type, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int surf_prim_add(bContext *C, wmOperator *op, int type) {
|
|
|
|
return curvesurf_prim_add(C, op, type, 1);
|
|
|
|
}
|
|
|
|
|
2010-06-13 05:48:21 +00:00
|
|
|
/* ******************** Curves ******************* */
|
2010-05-23 02:02:04 +00:00
|
|
|
|
|
|
|
static int add_primitive_bezier_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2010-05-24 07:14:55 +00:00
|
|
|
return curve_prim_add(C, op, CU_BEZIER|CU_PRIM_CURVE);
|
2010-05-23 02:02:04 +00:00
|
|
|
}
|
|
|
|
|
2010-05-24 07:14:55 +00:00
|
|
|
void CURVE_OT_primitive_bezier_curve_add(wmOperatorType *ot)
|
2010-05-23 02:02:04 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Add Bezier";
|
|
|
|
ot->description= "Construct a Bezier Curve";
|
2010-05-24 07:14:55 +00:00
|
|
|
ot->idname= "CURVE_OT_primitive_bezier_curve_add";
|
2010-05-23 02:02:04 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= ED_object_add_generic_invoke;
|
|
|
|
ot->exec= add_primitive_bezier_exec;
|
|
|
|
ot->poll= ED_operator_scene_editable;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
ED_object_add_generic_props(ot, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int add_primitive_bezier_circle_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2010-05-24 07:14:55 +00:00
|
|
|
return curve_prim_add(C, op, CU_BEZIER|CU_PRIM_CIRCLE);
|
2010-05-23 02:02:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CURVE_OT_primitive_bezier_circle_add(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Add Circle";
|
|
|
|
ot->description= "Construct a Bezier Circle";
|
|
|
|
ot->idname= "CURVE_OT_primitive_bezier_circle_add";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= ED_object_add_generic_invoke;
|
|
|
|
ot->exec= add_primitive_bezier_circle_exec;
|
|
|
|
ot->poll= ED_operator_scene_editable;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
ED_object_add_generic_props(ot, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int add_primitive_nurbs_curve_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2010-05-24 07:14:55 +00:00
|
|
|
return curve_prim_add(C, op, CU_NURBS|CU_PRIM_CURVE);
|
2010-05-23 02:02:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CURVE_OT_primitive_nurbs_curve_add(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Add Nurbs Curve";
|
|
|
|
ot->description= "Construct a Nurbs Curve";
|
|
|
|
ot->idname= "CURVE_OT_primitive_nurbs_curve_add";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= ED_object_add_generic_invoke;
|
|
|
|
ot->exec= add_primitive_nurbs_curve_exec;
|
|
|
|
ot->poll= ED_operator_scene_editable;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
ED_object_add_generic_props(ot, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int add_primitive_nurbs_circle_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2010-05-24 07:14:55 +00:00
|
|
|
return curve_prim_add(C, op, CU_NURBS|CU_PRIM_CIRCLE);
|
2010-05-23 02:02:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CURVE_OT_primitive_nurbs_circle_add(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Add Nurbs Circle";
|
|
|
|
ot->description= "Construct a Nurbs Circle";
|
|
|
|
ot->idname= "CURVE_OT_primitive_nurbs_circle_add";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= ED_object_add_generic_invoke;
|
|
|
|
ot->exec= add_primitive_nurbs_circle_exec;
|
|
|
|
ot->poll= ED_operator_scene_editable;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
ED_object_add_generic_props(ot, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int add_primitive_curve_path_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2010-05-24 07:14:55 +00:00
|
|
|
return curve_prim_add(C, op, CU_NURBS|CU_PRIM_PATH);
|
2010-05-23 02:02:04 +00:00
|
|
|
}
|
|
|
|
|
2010-05-24 07:14:55 +00:00
|
|
|
void CURVE_OT_primitive_nurbs_path_add(wmOperatorType *ot)
|
2010-05-23 02:02:04 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Add Path";
|
|
|
|
ot->description= "Construct a Path";
|
2010-05-24 07:14:55 +00:00
|
|
|
ot->idname= "CURVE_OT_primitive_nurbs_path_add";
|
2010-05-23 02:02:04 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= ED_object_add_generic_invoke;
|
|
|
|
ot->exec= add_primitive_curve_path_exec;
|
|
|
|
ot->poll= ED_operator_scene_editable;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
ED_object_add_generic_props(ot, TRUE);
|
|
|
|
}
|
|
|
|
|
2010-06-13 05:48:21 +00:00
|
|
|
/* **************** NURBS surfaces ********************** */
|
|
|
|
static int add_primitive_nurbs_surface_curve_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2010-06-22 21:11:13 +00:00
|
|
|
return surf_prim_add(C, op, CU_PRIM_CURVE|CU_NURBS);
|
2010-06-13 05:48:21 +00:00
|
|
|
}
|
2010-05-23 02:02:04 +00:00
|
|
|
|
2010-06-13 05:48:21 +00:00
|
|
|
void SURFACE_OT_primitive_nurbs_surface_curve_add(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Add Surface Curve";
|
|
|
|
ot->description= "Construct a Nurbs surface Curve";
|
|
|
|
ot->idname= "SURFACE_OT_primitive_nurbs_surface_curve_add";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= ED_object_add_generic_invoke;
|
|
|
|
ot->exec= add_primitive_nurbs_surface_curve_exec;
|
|
|
|
ot->poll= ED_operator_scene_editable;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
ED_object_add_generic_props(ot, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int add_primitive_nurbs_surface_circle_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2010-06-22 21:11:13 +00:00
|
|
|
return surf_prim_add(C, op, CU_PRIM_CIRCLE|CU_NURBS);
|
2010-06-13 05:48:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SURFACE_OT_primitive_nurbs_surface_circle_add(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Add Surface Circle";
|
|
|
|
ot->description= "Construct a Nurbs surface Circle";
|
|
|
|
ot->idname= "SURFACE_OT_primitive_nurbs_surface_circle_add";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= ED_object_add_generic_invoke;
|
|
|
|
ot->exec= add_primitive_nurbs_surface_circle_exec;
|
|
|
|
ot->poll= ED_operator_scene_editable;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
ED_object_add_generic_props(ot, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int add_primitive_nurbs_surface_surface_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2010-06-22 21:11:13 +00:00
|
|
|
return surf_prim_add(C, op, CU_PRIM_PATCH|CU_NURBS);
|
2010-06-13 05:48:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SURFACE_OT_primitive_nurbs_surface_surface_add(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Add Surface Patch";
|
|
|
|
ot->description= "Construct a Nurbs surface Patch";
|
|
|
|
ot->idname= "SURFACE_OT_primitive_nurbs_surface_surface_add";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= ED_object_add_generic_invoke;
|
|
|
|
ot->exec= add_primitive_nurbs_surface_surface_exec;
|
|
|
|
ot->poll= ED_operator_scene_editable;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
ED_object_add_generic_props(ot, TRUE);
|
|
|
|
}
|
|
|
|
|
2010-09-01 21:11:33 +00:00
|
|
|
static int add_primitive_nurbs_surface_cylinder_exec(bContext *C, wmOperator *op)
|
2010-06-13 05:48:21 +00:00
|
|
|
{
|
2010-06-22 21:11:13 +00:00
|
|
|
return surf_prim_add(C, op, CU_PRIM_TUBE|CU_NURBS);
|
2010-06-13 05:48:21 +00:00
|
|
|
}
|
|
|
|
|
2010-09-01 21:11:33 +00:00
|
|
|
void SURFACE_OT_primitive_nurbs_surface_cylinder_add(wmOperatorType *ot)
|
2010-06-13 05:48:21 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
2010-09-01 21:11:33 +00:00
|
|
|
ot->name= "Add Surface Cylinder";
|
|
|
|
ot->description= "Construct a Nurbs surface Cylinder";
|
|
|
|
ot->idname= "SURFACE_OT_primitive_nurbs_surface_cylinder_add";
|
2010-06-13 05:48:21 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= ED_object_add_generic_invoke;
|
2010-09-01 21:11:33 +00:00
|
|
|
ot->exec= add_primitive_nurbs_surface_cylinder_exec;
|
2010-06-13 05:48:21 +00:00
|
|
|
ot->poll= ED_operator_scene_editable;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
ED_object_add_generic_props(ot, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int add_primitive_nurbs_surface_sphere_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2010-06-22 21:11:13 +00:00
|
|
|
return surf_prim_add(C, op, CU_PRIM_SPHERE|CU_NURBS);
|
2010-06-13 05:48:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SURFACE_OT_primitive_nurbs_surface_sphere_add(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Add Surface Sphere";
|
|
|
|
ot->description= "Construct a Nurbs surface Sphere";
|
|
|
|
ot->idname= "SURFACE_OT_primitive_nurbs_surface_sphere_add";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= ED_object_add_generic_invoke;
|
|
|
|
ot->exec= add_primitive_nurbs_surface_sphere_exec;
|
|
|
|
ot->poll= ED_operator_scene_editable;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
ED_object_add_generic_props(ot, TRUE);
|
|
|
|
}
|
|
|
|
|
2010-09-01 20:18:31 +00:00
|
|
|
static int add_primitive_nurbs_surface_torus_exec(bContext *C, wmOperator *op)
|
2010-06-13 05:48:21 +00:00
|
|
|
{
|
2010-06-22 21:11:13 +00:00
|
|
|
return surf_prim_add(C, op, CU_PRIM_DONUT|CU_NURBS);
|
2010-06-13 05:48:21 +00:00
|
|
|
}
|
|
|
|
|
2010-09-01 20:18:31 +00:00
|
|
|
void SURFACE_OT_primitive_nurbs_surface_torus_add(wmOperatorType *ot)
|
2010-06-13 05:48:21 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
2010-09-01 20:18:31 +00:00
|
|
|
ot->name= "Add Surface Torus";
|
|
|
|
ot->description= "Construct a Nurbs surface Torus";
|
|
|
|
ot->idname= "SURFACE_OT_primitive_nurbs_surface_torus_add";
|
2010-06-13 05:48:21 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= ED_object_add_generic_invoke;
|
2010-09-01 20:18:31 +00:00
|
|
|
ot->exec= add_primitive_nurbs_surface_torus_exec;
|
2010-06-13 05:48:21 +00:00
|
|
|
ot->poll= ED_operator_scene_editable;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
ED_object_add_generic_props(ot, TRUE);
|
|
|
|
}
|
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
|
|
|
{
|
2009-02-11 23:02:21 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-09-08 07:35:07 +00:00
|
|
|
Curve *cu= obedit->data;
|
2009-01-14 12:26:45 +00:00
|
|
|
ListBase *editnurb= curve_get_editcurve(obedit);
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
for(nu= editnurb->first; nu; nu= nu->next) {
|
|
|
|
if( nu->bezt ) {
|
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a--) {
|
2009-09-08 07:35:07 +00:00
|
|
|
if(BEZSELECTED_HIDDENHANDLES(cu, bezt)) bezt->alfa= 0.0;
|
2009-01-14 12:26:45 +00:00
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(nu->bp) {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
while(a--) {
|
|
|
|
if(bp->f1 & SELECT) bp->alfa= 0.0;
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +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 */
|
|
|
|
ot->name= "Clear Tilt";
|
2009-03-29 02:15:13 +00:00
|
|
|
ot->idname= "CURVE_OT_tilt_clear";
|
2009-02-11 23:02:21 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= clear_tilt_exec;
|
|
|
|
ot->poll= ED_operator_editcurve;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
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
|
|
|
|
2010-04-30 04:48:40 +00:00
|
|
|
static void *undo_check_lastsel(void *lastsel, Nurb *nu, Nurb *newnu)
|
|
|
|
{
|
|
|
|
if (nu->bezt) {
|
|
|
|
BezTriple *lastbezt= (BezTriple*)lastsel;
|
|
|
|
if (lastbezt >= nu->bezt && lastbezt < nu->bezt + nu->pntsu) {
|
|
|
|
return newnu->bezt + (lastbezt - nu->bezt);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
BPoint *lastbp= (BPoint*)lastsel;
|
|
|
|
if (lastbp >= nu->bp && lastbp < nu->bp + nu->pntsu*nu->pntsv) {
|
|
|
|
return newnu->bp + (lastbp - nu->bp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-12-06 17:49:57 +00:00
|
|
|
static void undoCurve_to_editCurve(void *ucu, void *obe)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2010-12-06 17:49:57 +00:00
|
|
|
Object *obedit= obe;
|
|
|
|
Curve *cu= (Curve*)obedit->data;
|
2010-04-30 04:48:40 +00:00
|
|
|
UndoCurve *undoCurve= ucu;
|
|
|
|
ListBase *undobase= &undoCurve->nubase;
|
2010-07-25 11:57:36 +00:00
|
|
|
ListBase *editbase= ED_curve_editnurbs(cu);
|
2009-01-14 12:26:45 +00:00
|
|
|
Nurb *nu, *newnu;
|
2010-07-25 11:57:36 +00:00
|
|
|
EditNurb *editnurb= cu->editnurb;
|
2010-04-30 04:48:40 +00:00
|
|
|
void *lastsel= NULL;
|
2010-12-20 19:47:16 +00:00
|
|
|
AnimData *ad= BKE_animdata_from_id(&cu->id);
|
2010-04-30 04:48:40 +00:00
|
|
|
|
|
|
|
freeNurblist(editbase);
|
2009-01-14 12:26:45 +00:00
|
|
|
|
2010-07-25 11:57:36 +00:00
|
|
|
if (undoCurve->undoIndex) {
|
2010-12-06 17:20:22 +00:00
|
|
|
BLI_ghash_free(editnurb->keyindex, NULL, (GHashValFreeFP)free_cvKeyIndex);
|
2010-07-25 11:57:36 +00:00
|
|
|
editnurb->keyindex= dupli_keyIndexHash(undoCurve->undoIndex);
|
|
|
|
}
|
|
|
|
|
2010-12-20 19:47:16 +00:00
|
|
|
if(ad && ad->action) {
|
|
|
|
free_fcurves(&ad->action->curves);
|
|
|
|
copy_fcurves(&ad->action->curves, &undoCurve->fcurves);
|
|
|
|
}
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
/* copy */
|
2010-04-30 04:48:40 +00:00
|
|
|
for(nu= undobase->first; nu; nu= nu->next) {
|
2009-01-14 12:26:45 +00:00
|
|
|
newnu= duplicateNurb(nu);
|
2010-04-30 04:48:40 +00:00
|
|
|
|
|
|
|
if (lastsel == NULL) {
|
|
|
|
lastsel= undo_check_lastsel(undoCurve->lastsel, nu, newnu);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
|
|
cu->lastsel= lastsel;
|
2010-12-06 17:49:57 +00:00
|
|
|
|
|
|
|
ED_curve_updateAnimPaths(obedit);
|
2009-01-14 12:26:45 +00:00
|
|
|
}
|
|
|
|
|
2010-12-06 17:49:57 +00:00
|
|
|
static void *editCurve_to_undoCurve(void *obe)
|
2009-01-14 12:26:45 +00:00
|
|
|
{
|
2010-12-06 17:49:57 +00:00
|
|
|
Object *obedit= obe;
|
|
|
|
Curve *cu= (Curve*)obedit->data;
|
2010-07-25 11:57:36 +00:00
|
|
|
ListBase *nubase= ED_curve_editnurbs(cu);
|
2010-04-30 04:48:40 +00:00
|
|
|
UndoCurve *undoCurve;
|
2010-07-25 11:57:36 +00:00
|
|
|
EditNurb *editnurb= cu->editnurb, tmpEditnurb;
|
2009-01-14 12:26:45 +00:00
|
|
|
Nurb *nu, *newnu;
|
2010-04-30 04:48:40 +00:00
|
|
|
void *lastsel= NULL;
|
2010-12-20 19:47:16 +00:00
|
|
|
AnimData *ad= BKE_animdata_from_id(&cu->id);
|
2010-04-30 04:48:40 +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) {
|
|
|
|
undoCurve->undoIndex= dupli_keyIndexHash(editnurb->keyindex);
|
|
|
|
tmpEditnurb.keyindex= undoCurve->undoIndex;
|
|
|
|
}
|
|
|
|
|
2010-12-20 19:47:16 +00:00
|
|
|
if(ad && ad->action)
|
|
|
|
copy_fcurves(&undoCurve->fcurves, &ad->action->curves);
|
|
|
|
|
2009-01-14 12:26:45 +00:00
|
|
|
/* copy */
|
2010-04-30 04:48:40 +00:00
|
|
|
for(nu= nubase->first; nu; nu= nu->next) {
|
2009-01-14 12:26:45 +00:00
|
|
|
newnu= duplicateNurb(nu);
|
2010-04-30 04:48:40 +00:00
|
|
|
|
|
|
|
if (lastsel == NULL) {
|
|
|
|
lastsel= undo_check_lastsel(cu->lastsel, nu, newnu);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
|
|
undoCurve->lastsel= lastsel;
|
|
|
|
|
|
|
|
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
|
|
|
{
|
2010-04-30 04:48:40 +00:00
|
|
|
UndoCurve *undoCurve= ucv;
|
|
|
|
|
|
|
|
freeNurblist(&undoCurve->nubase);
|
|
|
|
|
2010-12-20 19:47:16 +00:00
|
|
|
if(undoCurve->undoIndex)
|
2010-12-06 17:20:22 +00:00
|
|
|
BLI_ghash_free(undoCurve->undoIndex, NULL, (GHashValFreeFP)free_cvKeyIndex);
|
2010-12-20 19:47:16 +00:00
|
|
|
|
|
|
|
free_fcurves(&undoCurve->fcurves);
|
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)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
|
|
|
/* Get list of nurbs from editnurbs structure */
|
|
|
|
ListBase *ED_curve_editnurbs(Curve *cu)
|
|
|
|
{
|
|
|
|
if (cu->editnurb) {
|
|
|
|
return &cu->editnurb->nurbs;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
void ED_curve_beztcpy(EditNurb *editnurb, BezTriple *dst, BezTriple *src, int count)
|
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
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
|
|
|
}
|