2012-02-06 06:10:11 +00:00
|
|
|
/*
|
|
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s): Joseph Eagar.
|
|
|
|
|
*
|
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
|
*/
|
|
|
|
|
|
2011-05-09 14:32:55 +00:00
|
|
|
#ifndef _BMESH_OPERATOR_API_H
|
|
|
|
|
#define _BMESH_OPERATOR_API_H
|
2009-03-09 10:38:36 +00:00
|
|
|
|
2010-07-14 22:06:10 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
|
extern "C" {
|
|
|
|
|
#endif
|
|
|
|
|
|
2009-03-09 10:38:36 +00:00
|
|
|
#include "BLI_memarena.h"
|
|
|
|
|
#include "BLI_ghash.h"
|
|
|
|
|
|
2009-09-06 02:43:36 +00:00
|
|
|
#include "BKE_utildefines.h"
|
|
|
|
|
|
2009-03-09 10:38:36 +00:00
|
|
|
#include <stdarg.h>
|
2011-11-16 19:06:38 +00:00
|
|
|
#include <string.h> /* for memcpy */
|
2009-03-09 10:38:36 +00:00
|
|
|
|
|
|
|
|
/*
|
2012-01-22 18:44:44 +00:00
|
|
|
* operators represent logical, executable mesh modules. all topological
|
|
|
|
|
* operations involving a bmesh has to go through them.
|
|
|
|
|
*
|
|
|
|
|
* operators are nested, as are tool flags, which are private to an operator
|
|
|
|
|
* when it's executed. tool flags are allocated in layers, one per operator
|
|
|
|
|
* execution, and are used for all internal flagging a tool needs to do.
|
|
|
|
|
*
|
|
|
|
|
* each operator has a series of "slots," which can be of the following types:
|
|
|
|
|
* - simple numerical types
|
|
|
|
|
* - arrays of elements (e.g. arrays of faces).
|
|
|
|
|
* - hash mappings.
|
|
|
|
|
*
|
|
|
|
|
* each slot is identified by a slot code, as are each operator.
|
|
|
|
|
* operators, and their slots, are defined in bmesh_opdefines.c (with their
|
|
|
|
|
* execution functions prototyped in bmesh_operators_private.h), with all their
|
|
|
|
|
* operator code and slot codes defined in bmesh_operators.h. see
|
|
|
|
|
* bmesh_opdefines.c and the BMOpDefine struct for how to define new operators.
|
|
|
|
|
*
|
|
|
|
|
* in general, operators are fed arrays of elements, created using either
|
|
|
|
|
* BM_HeaderFlag_To_Slot or BM_Flag_To_Slot (or through one of the format
|
|
|
|
|
* specifyers in BMO_CallOpf or BMO_InitOpf). Note that multiple element
|
|
|
|
|
* types (e.g. faces and edges) can be fed to the same slot array. Operators
|
|
|
|
|
* act on this data, and possibly spit out data into output slots.
|
|
|
|
|
*
|
|
|
|
|
* some notes:
|
|
|
|
|
* - operators should never read from header flags (e.g. element->head.flag). for
|
|
|
|
|
* example, if you want an operator to only operate on selected faces, you
|
|
|
|
|
* should use BM_HeaderFlag_To_Slot to put the selected elements into a slot.
|
|
|
|
|
* - when you read from an element slot array or mapping, you can either tool-flag
|
|
|
|
|
* all the elements in it, or read them using an iterator APi (which is
|
|
|
|
|
* semantically similar to the iterator api in bmesh_iterators.h).
|
|
|
|
|
*/
|
2009-03-09 10:38:36 +00:00
|
|
|
|
|
|
|
|
struct GHashIterator;
|
|
|
|
|
|
2012-01-22 18:44:44 +00:00
|
|
|
/* slot type arrays are terminated by the last member
|
|
|
|
|
* having a slot type of 0.*/
|
2009-03-22 23:16:43 +00:00
|
|
|
#define BMOP_OPSLOT_SENTINEL 0
|
|
|
|
|
#define BMOP_OPSLOT_INT 1
|
|
|
|
|
#define BMOP_OPSLOT_FLT 2
|
|
|
|
|
#define BMOP_OPSLOT_PNT 3
|
2009-06-02 07:40:32 +00:00
|
|
|
#define BMOP_OPSLOT_MAT 4
|
2009-03-22 23:16:43 +00:00
|
|
|
#define BMOP_OPSLOT_VEC 7
|
2009-03-09 10:38:36 +00:00
|
|
|
|
2012-01-22 18:44:44 +00:00
|
|
|
/* after BMOP_OPSLOT_VEC, everything is
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2012-01-22 18:44:44 +00:00
|
|
|
* dynamically allocated arrays. we
|
|
|
|
|
* leave a space in the identifiers
|
|
|
|
|
* for future growth.
|
|
|
|
|
*/
|
2009-06-23 05:35:49 +00:00
|
|
|
//it's very important this remain a power of two
|
2009-03-22 23:16:43 +00:00
|
|
|
#define BMOP_OPSLOT_ELEMENT_BUF 8
|
|
|
|
|
#define BMOP_OPSLOT_MAPPING 9
|
|
|
|
|
#define BMOP_OPSLOT_TYPES 10
|
2009-03-09 10:38:36 +00:00
|
|
|
|
2012-01-22 18:44:44 +00:00
|
|
|
/* please ignore all these structures, don't touch them in tool code, except
|
|
|
|
|
* for when your defining an operator with BMOpDefine.*/
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2009-03-09 10:38:36 +00:00
|
|
|
typedef struct BMOpSlot{
|
|
|
|
|
int slottype;
|
|
|
|
|
int len;
|
|
|
|
|
int flag;
|
2012-02-06 06:03:46 +00:00
|
|
|
int index; /* index within slot array */
|
2009-03-09 10:38:36 +00:00
|
|
|
union {
|
|
|
|
|
int i;
|
2012-02-06 06:03:46 +00:00
|
|
|
float f;
|
|
|
|
|
void *p;
|
2009-03-09 10:38:36 +00:00
|
|
|
float vec[3];
|
|
|
|
|
void *buf;
|
|
|
|
|
GHash *ghash;
|
|
|
|
|
} data;
|
2009-07-26 14:58:31 +00:00
|
|
|
} BMOpSlot;
|
2009-03-09 10:38:36 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
#define BMOP_MAX_SLOTS 16 /* way more than probably needed */
|
2009-03-09 10:38:36 +00:00
|
|
|
|
2010-07-14 22:06:10 +00:00
|
|
|
#ifdef slots
|
|
|
|
|
#undef slots
|
|
|
|
|
#endif
|
|
|
|
|
|
2009-03-09 10:38:36 +00:00
|
|
|
typedef struct BMOperator {
|
|
|
|
|
int type;
|
|
|
|
|
int slottype;
|
|
|
|
|
int needflag;
|
2011-04-13 22:30:25 +00:00
|
|
|
int flag;
|
2009-03-09 10:38:36 +00:00
|
|
|
struct BMOpSlot slots[BMOP_MAX_SLOTS];
|
|
|
|
|
void (*exec)(struct BMesh *bm, struct BMOperator *op);
|
|
|
|
|
MemArena *arena;
|
|
|
|
|
} BMOperator;
|
|
|
|
|
|
|
|
|
|
#define MAX_SLOTNAME 32
|
|
|
|
|
|
|
|
|
|
typedef struct slottype {
|
|
|
|
|
int type;
|
|
|
|
|
char name[MAX_SLOTNAME];
|
|
|
|
|
} slottype;
|
|
|
|
|
|
|
|
|
|
typedef struct BMOpDefine {
|
2011-02-27 06:19:40 +00:00
|
|
|
const char *name;
|
2009-03-09 10:38:36 +00:00
|
|
|
slottype slottypes[BMOP_MAX_SLOTS];
|
|
|
|
|
void (*exec)(BMesh *bm, BMOperator *op);
|
2011-03-29 05:48:18 +00:00
|
|
|
int flag;
|
2009-03-09 10:38:36 +00:00
|
|
|
} BMOpDefine;
|
|
|
|
|
|
2011-03-29 05:48:18 +00:00
|
|
|
/*BMOpDefine->flag*/
|
2011-04-13 22:30:25 +00:00
|
|
|
#define BMOP_UNTAN_MULTIRES 1 /*switch from multires tangent space to absolute coordinates*/
|
|
|
|
|
|
2011-03-29 05:48:18 +00:00
|
|
|
|
2012-01-22 18:44:44 +00:00
|
|
|
/* ensures consistent normals before operator execution,
|
|
|
|
|
* restoring the original ones windings/normals afterwards.
|
|
|
|
|
* keep in mind, this won't work if the input mesh isn't
|
|
|
|
|
* manifold.*/
|
2011-03-30 22:46:56 +00:00
|
|
|
#define BMOP_RATIONALIZE_NORMALS 2
|
|
|
|
|
|
2009-03-09 10:38:36 +00:00
|
|
|
/*------------- Operator API --------------*/
|
|
|
|
|
|
2012-01-22 18:44:44 +00:00
|
|
|
/* data types that use pointers (arrays, etc) should never
|
|
|
|
|
* have it set directly. and never use BMO_Set_Pnt to
|
|
|
|
|
* pass in a list of edges or any arrays, really.*/
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2011-11-16 14:36:23 +00:00
|
|
|
void BMO_Init_Op(struct BMesh *bm, struct BMOperator *op, const char *opname);
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2012-01-22 18:44:44 +00:00
|
|
|
/* executes an operator, pushing and popping a new tool flag
|
|
|
|
|
* layer as appropriate.*/
|
2009-03-09 10:38:36 +00:00
|
|
|
void BMO_Exec_Op(struct BMesh *bm, struct BMOperator *op);
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2012-01-22 18:44:44 +00:00
|
|
|
/* finishes an operator (though note the operator's tool flag is removed
|
|
|
|
|
* after it finishes executing in BMO_Exec_Op).*/
|
2009-03-09 10:38:36 +00:00
|
|
|
void BMO_Finish_Op(struct BMesh *bm, struct BMOperator *op);
|
|
|
|
|
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2012-01-22 18:44:44 +00:00
|
|
|
/* tool flag API. never, ever ever should tool code put junk in
|
|
|
|
|
* header flags (element->head.flag), nor should they use
|
|
|
|
|
* element->head.eflag1/eflag2. instead, use this api to set
|
|
|
|
|
* flags.
|
|
|
|
|
*
|
|
|
|
|
* if you need to store a value per element, use a
|
|
|
|
|
* ghash or a mapping slot to do it. */
|
|
|
|
|
|
|
|
|
|
/* flags 15 and 16 (1<<14 and 1<<15) are reserved for bmesh api use */
|
2010-09-25 01:54:58 +00:00
|
|
|
#define BMO_TestFlag(bm, element, flag) (((BMHeader*)(element))->flags[bm->stackdepth-1].f & (flag))
|
|
|
|
|
#define BMO_SetFlag(bm, element, flag) (((BMHeader*)(element))->flags[bm->stackdepth-1].f |= (flag))
|
|
|
|
|
#define BMO_ClearFlag(bm, element, flag) (((BMHeader*)(element))->flags[bm->stackdepth-1].f &= ~(flag))
|
2011-03-30 22:46:56 +00:00
|
|
|
#define BMO_ToggleFlag(bm, element, flag) (((BMHeader*)(element))->flags[bm->stackdepth-1].f ^= (flag))
|
2009-09-05 06:10:30 +00:00
|
|
|
|
|
|
|
|
/*profiling showed a significant amount of time spent in BMO_TestFlag
|
2009-03-09 10:38:36 +00:00
|
|
|
void BMO_SetFlag(struct BMesh *bm, void *element, int flag);
|
|
|
|
|
void BMO_ClearFlag(struct BMesh *bm, void *element, int flag);
|
2009-09-05 06:10:30 +00:00
|
|
|
int BMO_TestFlag(struct BMesh *bm, void *element, int flag);*/
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* count the number of elements with a specific flag.
|
|
|
|
|
* type can be a bitmask of BM_FACE, BM_EDGE, or BM_FACE. */
|
2011-11-01 14:36:23 +00:00
|
|
|
int BMO_CountFlag(struct BMesh *bm, int flag, const char htype);
|
2009-03-09 10:38:36 +00:00
|
|
|
|
|
|
|
|
/*---------formatted operator initialization/execution-----------*/
|
|
|
|
|
/*
|
2012-01-22 18:44:44 +00:00
|
|
|
* this system is used to execute or initialize an operator,
|
|
|
|
|
* using a formatted-string system.
|
|
|
|
|
*
|
|
|
|
|
* for example, BMO_CallOpf(bm, "del geom=%hf context=%d", BM_SELECT, DEL_FACES);
|
|
|
|
|
* . . .will execute the delete operator, feeding in selected faces, deleting them.
|
|
|
|
|
*
|
|
|
|
|
* the basic format for the format string is:
|
|
|
|
|
* [operatorname] [slotname]=%[code] [slotname]=%[code]
|
|
|
|
|
*
|
|
|
|
|
* as in printf, you pass in one additional argument to the function
|
|
|
|
|
* for every code.
|
|
|
|
|
*
|
|
|
|
|
* the formatting codes are:
|
|
|
|
|
* %d - put int in slot
|
|
|
|
|
* %f - put float in slot
|
|
|
|
|
* %p - put pointer in slot
|
|
|
|
|
* %h[f/e/v] - put elements with a header flag in slot.
|
|
|
|
|
* the letters after %h define which element types to use,
|
|
|
|
|
* so e.g. %hf will do faces, %hfe will do faces and edges,
|
|
|
|
|
* %hv will do verts, etc. must pass in at least one
|
|
|
|
|
* element type letter.
|
|
|
|
|
* %f[f/e/v] - same as %h, except it deals with tool flags instead of
|
|
|
|
|
* header flags.
|
|
|
|
|
* %a[f/e/v] - pass all elements (of types specified by f/e/v) to the
|
|
|
|
|
* slot.
|
|
|
|
|
* %e - pass in a single element.
|
|
|
|
|
* %v - pointer to a float vector of length 3.
|
|
|
|
|
* %m[3/4] - matrix, 3/4 refers to the matrix size, 3 or 4. the
|
|
|
|
|
* corrusponding argument must be a pointer to
|
|
|
|
|
* a float matrix.
|
|
|
|
|
* %s - copy a slot from another op, instead of mapping to one
|
|
|
|
|
* argument, it maps to two, a pointer to an operator and
|
|
|
|
|
* a slot name.
|
|
|
|
|
*/
|
2011-02-27 06:19:40 +00:00
|
|
|
void BMO_push(BMesh *bm, BMOperator *op);
|
|
|
|
|
void BMO_pop(BMesh *bm);
|
|
|
|
|
|
2009-03-09 10:38:36 +00:00
|
|
|
/*executes an operator*/
|
2011-02-27 06:19:40 +00:00
|
|
|
int BMO_CallOpf(BMesh *bm, const char *fmt, ...);
|
2009-03-09 10:38:36 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* initializes, but doesn't execute an operator. this is so you can
|
|
|
|
|
* gain access to the outputs of the operator. note that you have
|
|
|
|
|
* to execute/finitsh (BMO_Exec_Op and BMO_Finish_Op) yourself. */
|
2011-02-27 06:19:40 +00:00
|
|
|
int BMO_InitOpf(BMesh *bm, BMOperator *op, const char *fmt, ...);
|
2009-03-09 10:38:36 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* va_list version, used to implement the above two functions,
|
|
|
|
|
* plus EDBM_CallOpf in bmeshutils.c. */
|
2011-02-27 06:19:40 +00:00
|
|
|
int BMO_VInitOpf(BMesh *bm, BMOperator *op, const char *fmt, va_list vlist);
|
2009-03-09 10:38:36 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* test whether a named slot exists */
|
2011-10-12 14:16:05 +00:00
|
|
|
int BMO_HasSlot(struct BMOperator *op, const char *slotname);
|
|
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* get a pointer to a slot. this may be removed layer on from the public API. */
|
2011-02-27 06:19:40 +00:00
|
|
|
BMOpSlot *BMO_GetSlot(struct BMOperator *op, const char *slotname);
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* copies the data of a slot from one operator to another. src and dst are the
|
|
|
|
|
* source/destination slot codes, respectively. */
|
2009-03-22 23:16:43 +00:00
|
|
|
void BMO_CopySlot(struct BMOperator *source_op, struct BMOperator *dest_op,
|
2011-02-27 06:19:40 +00:00
|
|
|
const char *src, const char *dst);
|
2009-03-09 10:38:36 +00:00
|
|
|
|
2009-08-18 20:05:08 +00:00
|
|
|
/*remove tool flagged elements*/
|
|
|
|
|
void BM_remove_tagged_faces(struct BMesh *bm, int flag);
|
|
|
|
|
void BM_remove_tagged_edges(struct BMesh *bm, int flag);
|
|
|
|
|
void BM_remove_tagged_verts(struct BMesh *bm, int flag);
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2011-04-13 22:30:25 +00:00
|
|
|
void BMO_Set_OpFlag(struct BMesh *bm, struct BMOperator *op, int flag);
|
|
|
|
|
void BMO_Clear_OpFlag(struct BMesh *bm, struct BMOperator *op, int flag);
|
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
void BMO_Set_Float(struct BMOperator *op, const char *slotname, float f);
|
|
|
|
|
float BMO_Get_Float(BMOperator *op, const char *slotname);
|
|
|
|
|
void BMO_Set_Int(struct BMOperator *op, const char *slotname, int i);
|
|
|
|
|
int BMO_Get_Int(BMOperator *op, const char *slotname);
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* don't pass in arrays that are supposed to map to elements this way.
|
|
|
|
|
*
|
|
|
|
|
* so, e.g. passing in list of floats per element in another slot is bad.
|
|
|
|
|
* passing in, e.g. pointer to an editmesh for the conversion operator is fine
|
|
|
|
|
* though. */
|
2011-02-27 06:19:40 +00:00
|
|
|
void BMO_Set_Pnt(struct BMOperator *op, const char *slotname, void *p);
|
|
|
|
|
void *BMO_Get_Pnt(BMOperator *op, const char *slotname);
|
2011-12-12 23:58:05 +00:00
|
|
|
void BMO_Set_Vec(struct BMOperator *op, const char *slotname, const float vec[3]);
|
|
|
|
|
void BMO_Get_Vec(BMOperator *op, const char *slotname, float r_vec[3]);
|
2009-03-09 10:38:36 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* only supports square mats */
|
|
|
|
|
/* size must be 3 or 4; this api is meant only for transformation matrices.
|
|
|
|
|
* note that internally the matrix is stored in 4x4 form, and it's safe to
|
|
|
|
|
* call whichever BMO_Get_Mat* function you want. */
|
2011-02-27 06:19:40 +00:00
|
|
|
void BMO_Set_Mat(struct BMOperator *op, const char *slotname, float *mat, int size);
|
|
|
|
|
void BMO_Get_Mat4(struct BMOperator *op, const char *slotname, float mat[4][4]);
|
|
|
|
|
void BMO_Get_Mat3(struct BMOperator *op, const char *slotname, float mat[3][3]);
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2011-11-01 14:36:23 +00:00
|
|
|
void BMO_Clear_Flag_All(BMesh *bm, BMOperator *op, const char htype, int flag);
|
2009-08-12 03:51:28 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* puts every element of type type (which is a bitmask) with tool flag flag,
|
|
|
|
|
* into a slot. */
|
2012-02-06 06:26:54 +00:00
|
|
|
void BMO_Flag_To_Slot(struct BMesh *bm, struct BMOperator *op, const char *slotname,
|
|
|
|
|
const int flag, const char htype);
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* tool-flags all elements inside an element slot array with flag flag. */
|
2012-02-06 06:26:54 +00:00
|
|
|
void BMO_Flag_Buffer(struct BMesh *bm, struct BMOperator *op, const char *slotname,
|
|
|
|
|
const int hflag, const char htype);
|
2012-02-06 06:03:46 +00:00
|
|
|
/* clears tool-flag flag from all elements inside a slot array. */
|
2012-02-06 06:26:54 +00:00
|
|
|
void BMO_Unflag_Buffer(struct BMesh *bm, struct BMOperator *op, const char *slotname,
|
|
|
|
|
const int flag, const char htype);
|
2009-03-09 10:38:36 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* tool-flags all elements inside an element slot array with flag flag. */
|
2012-02-06 06:26:54 +00:00
|
|
|
void BMO_HeaderFlag_Buffer(struct BMesh *bm, struct BMOperator *op, const char *slotname,
|
|
|
|
|
const char hflag, const char htype);
|
2012-02-06 06:03:46 +00:00
|
|
|
/* clears tool-flag flag from all elements inside a slot array. */
|
2012-02-06 06:26:54 +00:00
|
|
|
void BMO_UnHeaderFlag_Buffer(struct BMesh *bm, struct BMOperator *op, const char *slotname,
|
|
|
|
|
const char hflag, const char htype);
|
2009-06-18 01:31:50 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* puts every element of type type (which is a bitmask) with header flag
|
|
|
|
|
* flag, into a slot. note: ignores hidden elements (e.g. elements with
|
|
|
|
|
* header flag BM_HIDDEN set).*/
|
2012-02-06 06:26:54 +00:00
|
|
|
void BMO_HeaderFlag_To_Slot(struct BMesh *bm, struct BMOperator *op, const char *slotname,
|
|
|
|
|
const char hflag, const char htype);
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* counts number of elements inside a slot array. */
|
2011-02-27 06:19:40 +00:00
|
|
|
int BMO_CountSlotBuf(struct BMesh *bm, struct BMOperator *op, const char *slotname);
|
|
|
|
|
int BMO_CountSlotMap(struct BMesh *bm, struct BMOperator *op, const char *slotname);
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* Counts the number of edges with tool flag toolflag around
|
|
|
|
|
*/
|
2009-09-12 08:41:39 +00:00
|
|
|
int BMO_Vert_CountEdgeFlags(BMesh *bm, BMVert *v, int toolflag);
|
|
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* inserts a key/value mapping into a mapping slot. note that it copies the
|
|
|
|
|
* value, it doesn't store a reference to it. */
|
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
//BM_INLINE void BMO_Insert_Mapping(BMesh *bm, BMOperator *op, const char *slotname,
|
2009-09-09 06:28:58 +00:00
|
|
|
//void *element, void *data, int len);
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* inserts a key/float mapping pair into a mapping slot. */
|
2011-02-27 06:19:40 +00:00
|
|
|
//BM_INLINE void BMO_Insert_MapFloat(BMesh *bm, BMOperator *op, const char *slotname,
|
2009-09-09 06:28:58 +00:00
|
|
|
//void *element, float val);
|
2009-03-14 02:52:16 +00:00
|
|
|
|
|
|
|
|
//returns 1 if the specified pointer is in the map.
|
2011-02-27 06:19:40 +00:00
|
|
|
//BM_INLINE int BMO_InMap(BMesh *bm, BMOperator *op, const char *slotname, void *element);
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* returns a point to the value of a specific key. */
|
2011-02-27 06:19:40 +00:00
|
|
|
//BM_INLINE void *BMO_Get_MapData(BMesh *bm, BMOperator *op, const char *slotname, void *element);
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* returns the float part of a key/float pair. */
|
2011-02-27 06:19:40 +00:00
|
|
|
//BM_INLINE float BMO_Get_MapFloat(BMesh *bm, BMOperator *op, const char *slotname, void *element);
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* flags all elements in a mapping. note that the mapping must only have
|
|
|
|
|
* bmesh elements in it.*/
|
2009-03-09 10:38:36 +00:00
|
|
|
void BMO_Mapping_To_Flag(struct BMesh *bm, struct BMOperator *op,
|
2011-02-27 06:19:40 +00:00
|
|
|
const char *slotname, int flag);
|
2009-03-09 10:38:36 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* pointer versoins of BMO_Get_MapFloat and BMO_Insert_MapFloat.
|
|
|
|
|
*
|
|
|
|
|
* do NOT use these for non-operator-api-allocated memory! instead
|
|
|
|
|
* use BMO_Get_MapData and BMO_Insert_Mapping, which copies the data. */
|
2009-03-14 02:52:16 +00:00
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
//BM_INLINE void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, const char *slotname,
|
2009-09-09 06:28:58 +00:00
|
|
|
//void *key, void *val);
|
2011-02-27 06:19:40 +00:00
|
|
|
//BM_INLINE void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, const char *slotname,
|
2009-09-09 06:28:58 +00:00
|
|
|
//void *key);
|
2009-03-09 10:38:36 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* this part of the API is used to iterate over element buffer or
|
|
|
|
|
* mapping slots.
|
|
|
|
|
*
|
|
|
|
|
* for example, iterating over the faces in a slot is:
|
|
|
|
|
*
|
|
|
|
|
* BMOIter oiter;
|
|
|
|
|
* BMFace *f;
|
|
|
|
|
*
|
|
|
|
|
* f = BMO_IterNew(&oiter, bm, some_operator, "slotname", BM_FACE);
|
|
|
|
|
* for (; f; f=BMO_IterStep(&oiter)) {
|
|
|
|
|
* /do something with the face
|
|
|
|
|
* }
|
|
|
|
|
*
|
|
|
|
|
* another example, iterating over a mapping:
|
|
|
|
|
* BMOIter oiter;
|
|
|
|
|
* void *key;
|
|
|
|
|
* void *val;
|
|
|
|
|
*
|
|
|
|
|
* key = BMO_IterNew(&oiter, bm, some_operator, "slotname", 0);
|
|
|
|
|
* for (; key; key=BMO_IterStep(&oiter)) {
|
|
|
|
|
* val = BMO_IterMapVal(&oiter);
|
|
|
|
|
* //do something with the key/val pair
|
|
|
|
|
* //note that val is a pointer to the val data,
|
|
|
|
|
* //whether it's a float, pointer, whatever.
|
|
|
|
|
* //
|
|
|
|
|
* // so to get a pointer, for example, use:
|
|
|
|
|
* // *((void**)BMO_IterMapVal(&oiter));
|
|
|
|
|
* //or something like that.
|
|
|
|
|
* }
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* contents of this structure are private,
|
|
|
|
|
* don't directly access. */
|
2009-03-14 02:52:16 +00:00
|
|
|
typedef struct BMOIter {
|
|
|
|
|
BMOpSlot *slot;
|
|
|
|
|
int cur; //for arrays
|
|
|
|
|
struct GHashIterator giter;
|
|
|
|
|
void *val;
|
2011-11-01 14:36:23 +00:00
|
|
|
char restrictmask; /* bitwise '&' with BMHeader.htype */
|
2009-03-14 02:52:16 +00:00
|
|
|
} BMOIter;
|
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
void *BMO_FirstElem(BMOperator *op, const char *slotname);
|
2009-09-17 23:05:33 +00:00
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* restrictmask restricts the iteration to certain element types
|
|
|
|
|
* (e.g. combination of BM_VERT, BM_EDGE, BM_FACE), if iterating
|
|
|
|
|
* over an element buffer (not a mapping).*/
|
2009-03-09 10:38:36 +00:00
|
|
|
void *BMO_IterNew(BMOIter *iter, BMesh *bm, BMOperator *op,
|
2011-11-01 14:36:23 +00:00
|
|
|
const char *slotname, const char restrictmask);
|
2009-03-09 10:38:36 +00:00
|
|
|
void *BMO_IterStep(BMOIter *iter);
|
|
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* returns a pointer to the key value when iterating over mappings.
|
|
|
|
|
* remember for pointer maps this will be a pointer to a pointer.*/
|
2009-03-09 10:38:36 +00:00
|
|
|
void *BMO_IterMapVal(BMOIter *iter);
|
|
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* use this for pointer mappings */
|
2009-07-14 06:13:43 +00:00
|
|
|
void *BMO_IterMapValp(BMOIter *iter);
|
|
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* use this for float mappings */
|
2009-07-14 06:13:43 +00:00
|
|
|
float BMO_IterMapValf(BMOIter *iter);
|
|
|
|
|
|
2012-02-06 06:26:54 +00:00
|
|
|
#define BMO_ITER(ele, iter, bm, op, slotname, restrict) \
|
2009-06-23 05:35:49 +00:00
|
|
|
ele = BMO_IterNew(iter, bm, op, slotname, restrict); \
|
2009-05-28 04:41:02 +00:00
|
|
|
for ( ; ele; ele=BMO_IterStep(iter))
|
|
|
|
|
|
2009-09-09 06:28:58 +00:00
|
|
|
/******************* Inlined Functions********************/
|
|
|
|
|
typedef void (*opexec)(struct BMesh *bm, struct BMOperator *op);
|
|
|
|
|
|
2012-02-06 06:03:46 +00:00
|
|
|
/* mappings map elements to data, which
|
|
|
|
|
* follows the mapping struct in memory. */
|
2009-09-09 06:28:58 +00:00
|
|
|
typedef struct element_mapping {
|
|
|
|
|
BMHeader *element;
|
|
|
|
|
int len;
|
|
|
|
|
} element_mapping;
|
|
|
|
|
|
|
|
|
|
extern const int BMOP_OPSLOT_TYPEINFO[];
|
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
BM_INLINE void BMO_Insert_Mapping(BMesh *UNUSED(bm), BMOperator *op, const char *slotname,
|
2012-01-22 18:44:44 +00:00
|
|
|
void *element, void *data, int len) {
|
2009-09-09 06:28:58 +00:00
|
|
|
element_mapping *mapping;
|
|
|
|
|
BMOpSlot *slot = BMO_GetSlot(op, slotname);
|
|
|
|
|
|
|
|
|
|
/*sanity check*/
|
|
|
|
|
if (slot->slottype != BMOP_OPSLOT_MAPPING) return;
|
|
|
|
|
|
2010-07-14 22:06:10 +00:00
|
|
|
mapping = (element_mapping*) BLI_memarena_alloc(op->arena, sizeof(*mapping) + len);
|
2009-09-09 06:28:58 +00:00
|
|
|
|
2010-07-14 22:06:10 +00:00
|
|
|
mapping->element = (BMHeader*) element;
|
2009-09-09 06:28:58 +00:00
|
|
|
mapping->len = len;
|
|
|
|
|
memcpy(mapping+1, data, len);
|
|
|
|
|
|
|
|
|
|
if (!slot->data.ghash) {
|
2012-01-22 18:44:44 +00:00
|
|
|
slot->data.ghash = BLI_ghash_new(BLI_ghashutil_ptrhash,
|
|
|
|
|
BLI_ghashutil_ptrcmp, "bmesh op");
|
2009-09-09 06:28:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_ghash_insert(slot->data.ghash, element, mapping);
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
BM_INLINE void BMO_Insert_MapInt(BMesh *bm, BMOperator *op, const char *slotname,
|
2012-01-22 18:44:44 +00:00
|
|
|
void *element, int val)
|
2010-09-25 01:54:58 +00:00
|
|
|
{
|
|
|
|
|
BMO_Insert_Mapping(bm, op, slotname, element, &val, sizeof(int));
|
|
|
|
|
}
|
2009-09-09 06:28:58 +00:00
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
BM_INLINE void BMO_Insert_MapFloat(BMesh *bm, BMOperator *op, const char *slotname,
|
2012-01-22 18:44:44 +00:00
|
|
|
void *element, float val)
|
2009-09-09 06:28:58 +00:00
|
|
|
{
|
|
|
|
|
BMO_Insert_Mapping(bm, op, slotname, element, &val, sizeof(float));
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
BM_INLINE void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, const char *slotname,
|
2012-01-22 18:44:44 +00:00
|
|
|
void *element, void *val)
|
2009-09-09 06:28:58 +00:00
|
|
|
{
|
|
|
|
|
BMO_Insert_Mapping(bm, op, slotname, element, &val, sizeof(void*));
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
BM_INLINE int BMO_InMap(BMesh *UNUSED(bm), BMOperator *op, const char *slotname, void *element)
|
2009-09-09 06:28:58 +00:00
|
|
|
{
|
|
|
|
|
BMOpSlot *slot = BMO_GetSlot(op, slotname);
|
|
|
|
|
|
|
|
|
|
/*sanity check*/
|
|
|
|
|
if (slot->slottype != BMOP_OPSLOT_MAPPING) return 0;
|
|
|
|
|
if (!slot->data.ghash) return 0;
|
|
|
|
|
|
|
|
|
|
return BLI_ghash_haskey(slot->data.ghash, element);
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
BM_INLINE void *BMO_Get_MapData(BMesh *UNUSED(bm), BMOperator *op, const char *slotname,
|
2012-01-22 18:44:44 +00:00
|
|
|
void *element)
|
2009-09-09 06:28:58 +00:00
|
|
|
{
|
|
|
|
|
element_mapping *mapping;
|
|
|
|
|
BMOpSlot *slot = BMO_GetSlot(op, slotname);
|
|
|
|
|
|
|
|
|
|
/*sanity check*/
|
|
|
|
|
if (slot->slottype != BMOP_OPSLOT_MAPPING) return NULL;
|
|
|
|
|
if (!slot->data.ghash) return NULL;
|
|
|
|
|
|
2010-07-14 22:06:10 +00:00
|
|
|
mapping = (element_mapping*) BLI_ghash_lookup(slot->data.ghash, element);
|
2009-09-09 06:28:58 +00:00
|
|
|
|
|
|
|
|
if (!mapping) return NULL;
|
|
|
|
|
|
|
|
|
|
return mapping + 1;
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
BM_INLINE float BMO_Get_MapFloat(BMesh *bm, BMOperator *op, const char *slotname,
|
2012-01-22 18:44:44 +00:00
|
|
|
void *element)
|
2009-09-09 06:28:58 +00:00
|
|
|
{
|
2010-07-14 22:06:10 +00:00
|
|
|
float *val = (float*) BMO_Get_MapData(bm, op, slotname, element);
|
2009-09-09 06:28:58 +00:00
|
|
|
if (val) return *val;
|
|
|
|
|
|
|
|
|
|
return 0.0f;
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
BM_INLINE int BMO_Get_MapInt(BMesh *bm, BMOperator *op, const char *slotname,
|
2012-01-22 18:44:44 +00:00
|
|
|
void *element)
|
2010-09-25 01:54:58 +00:00
|
|
|
{
|
|
|
|
|
int *val = (int*) BMO_Get_MapData(bm, op, slotname, element);
|
|
|
|
|
if (val) return *val;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
BM_INLINE void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, const char *slotname,
|
2012-01-22 18:44:44 +00:00
|
|
|
void *element)
|
2009-09-09 06:28:58 +00:00
|
|
|
{
|
2010-07-14 22:06:10 +00:00
|
|
|
void **val = (void**) BMO_Get_MapData(bm, op, slotname, element);
|
2009-09-09 06:28:58 +00:00
|
|
|
if (val) return *val;
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-24 11:20:48 +00:00
|
|
|
BM_INLINE void BMO_SetIndex(BMesh *bm, const void *element, int index)
|
2011-11-22 19:57:37 +00:00
|
|
|
{
|
2011-11-24 11:20:48 +00:00
|
|
|
BMHeader *header = (BMHeader *)element;
|
|
|
|
|
header->flags[bm->stackdepth-1].index = index;
|
2011-11-22 19:57:37 +00:00
|
|
|
}
|
|
|
|
|
|
2011-11-24 11:20:48 +00:00
|
|
|
BM_INLINE int BMO_GetIndex(BMesh *bm, void *element)
|
2011-11-22 19:57:37 +00:00
|
|
|
{
|
2011-11-24 11:20:48 +00:00
|
|
|
BMHeader *header = (BMHeader *)element;
|
|
|
|
|
return header->flags[bm->stackdepth-1].index;
|
2011-11-22 19:57:37 +00:00
|
|
|
}
|
|
|
|
|
|
2010-07-14 22:06:10 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2011-05-09 14:32:55 +00:00
|
|
|
#endif /* _BMESH_OPERATOR_API_H */
|