542 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			542 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * ***** 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 *****
 | |
|  */
 | |
| 
 | |
| #ifndef _BMESH_OPERATOR_API_H
 | |
| #define _BMESH_OPERATOR_API_H
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| extern "C" {
 | |
| #endif
 | |
| 
 | |
| #include "BLI_memarena.h"
 | |
| #include "BLI_ghash.h"
 | |
| 
 | |
| #include "BKE_utildefines.h"
 | |
| 
 | |
| #include <stdarg.h>
 | |
| #include <string.h> /* for memcpy */
 | |
| 
 | |
| /*
 | |
|  * 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).
 | |
|  */
 | |
| 
 | |
| struct GHashIterator;
 | |
| 
 | |
| /* slot type arrays are terminated by the last member
 | |
|  * having a slot type of 0.*/
 | |
| #define BMOP_OPSLOT_SENTINEL		0
 | |
| #define BMOP_OPSLOT_INT			1
 | |
| #define BMOP_OPSLOT_FLT			2
 | |
| #define BMOP_OPSLOT_PNT			3
 | |
| #define BMOP_OPSLOT_MAT			4
 | |
| #define BMOP_OPSLOT_VEC			7
 | |
| 
 | |
| /* after BMOP_OPSLOT_VEC, everything is 
 | |
| 
 | |
|  * dynamically allocated arrays.  we
 | |
|  * leave a space in the identifiers
 | |
|  * for future growth.
 | |
|  */
 | |
| //it's very important this remain a power of two
 | |
| #define BMOP_OPSLOT_ELEMENT_BUF		8
 | |
| #define BMOP_OPSLOT_MAPPING		9
 | |
| #define BMOP_OPSLOT_TYPES		10
 | |
| 
 | |
| /* please ignore all these structures, don't touch them in tool code, except
 | |
|  * for when your defining an operator with BMOpDefine.*/
 | |
| 
 | |
| typedef struct BMOpSlot{
 | |
| 	int slottype;
 | |
| 	int len;
 | |
| 	int flag;
 | |
| 	int index; /* index within slot array */
 | |
| 	union {
 | |
| 		int i;
 | |
| 		float f;
 | |
| 		void *p;
 | |
| 		float vec[3];
 | |
| 		void *buf;
 | |
| 		GHash *ghash;
 | |
| 	} data;
 | |
| } BMOpSlot;
 | |
| 
 | |
| #define BMOP_MAX_SLOTS			16 /* way more than probably needed */
 | |
| 
 | |
| #ifdef slots
 | |
| #undef slots
 | |
| #endif
 | |
| 
 | |
| typedef struct BMOperator {
 | |
| 	int type;
 | |
| 	int slottype;
 | |
| 	int needflag;
 | |
| 	int flag;
 | |
| 	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 {
 | |
| 	const char *name;
 | |
| 	slottype slottypes[BMOP_MAX_SLOTS];
 | |
| 	void (*exec)(BMesh *bm, BMOperator *op);
 | |
| 	int flag; 
 | |
| } BMOpDefine;
 | |
| 
 | |
| /*BMOpDefine->flag*/
 | |
| #define BMOP_UNTAN_MULTIRES		1 /*switch from multires tangent space to absolute coordinates*/
 | |
| 
 | |
| 
 | |
| /* 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.*/
 | |
| #define BMOP_RATIONALIZE_NORMALS 2
 | |
| 
 | |
| /*------------- Operator API --------------*/
 | |
| 
 | |
| /* 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.*/
 | |
| 
 | |
| void BMO_Init_Op(struct BMesh *bm, struct BMOperator *op, const char *opname);
 | |
| 
 | |
| /* executes an operator, pushing and popping a new tool flag 
 | |
|  * layer as appropriate.*/
 | |
| void BMO_Exec_Op(struct BMesh *bm, struct BMOperator *op);
 | |
| 
 | |
| /* finishes an operator (though note the operator's tool flag is removed 
 | |
|  * after it finishes executing in BMO_Exec_Op).*/
 | |
| void BMO_Finish_Op(struct BMesh *bm, struct BMOperator *op);
 | |
| 
 | |
| 
 | |
| /* 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 */
 | |
| #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))
 | |
| #define BMO_ToggleFlag(bm, element, flag) (((BMHeader*)(element))->flags[bm->stackdepth-1].f ^= (flag))
 | |
| 
 | |
| /*profiling showed a significant amount of time spent in BMO_TestFlag
 | |
| void BMO_SetFlag(struct BMesh *bm, void *element, int flag);
 | |
| void BMO_ClearFlag(struct BMesh *bm, void *element, int flag);
 | |
| int BMO_TestFlag(struct BMesh *bm, void *element, int flag);*/
 | |
| 
 | |
| /* count the number of elements with a specific flag.
 | |
|  * type can be a bitmask of BM_FACE, BM_EDGE, or BM_FACE. */
 | |
| int BMO_CountFlag(struct BMesh *bm, int flag, const char htype);
 | |
| 
 | |
| /*---------formatted operator initialization/execution-----------*/
 | |
| /*
 | |
|  * 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.
 | |
|  */
 | |
| void BMO_push(BMesh *bm, BMOperator *op);
 | |
| void BMO_pop(BMesh *bm);
 | |
| 
 | |
| /*executes an operator*/
 | |
| int BMO_CallOpf(BMesh *bm, const char *fmt, ...);
 | |
| 
 | |
| /* 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. */
 | |
| int BMO_InitOpf(BMesh *bm, BMOperator *op, const char *fmt, ...);
 | |
| 
 | |
| /* va_list version, used to implement the above two functions,
 | |
|  * plus EDBM_CallOpf in bmeshutils.c. */
 | |
| int BMO_VInitOpf(BMesh *bm, BMOperator *op, const char *fmt, va_list vlist);
 | |
| 
 | |
| /* test whether a named slot exists */
 | |
| int BMO_HasSlot(struct BMOperator *op, const char *slotname);
 | |
| 
 | |
| /* get a pointer to a slot.  this may be removed layer on from the public API. */
 | |
| BMOpSlot *BMO_GetSlot(struct BMOperator *op, const char *slotname);
 | |
| 
 | |
| /* copies the data of a slot from one operator to another.  src and dst are the
 | |
|  * source/destination slot codes, respectively. */
 | |
| void BMO_CopySlot(struct BMOperator *source_op, struct BMOperator *dest_op, 
 | |
|                   const char *src, const char *dst);
 | |
| 
 | |
| /*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);
 | |
| 
 | |
| void BMO_Set_OpFlag(struct BMesh *bm, struct BMOperator *op, int flag);
 | |
| void BMO_Clear_OpFlag(struct BMesh *bm, struct BMOperator *op, int flag);
 | |
| 
 | |
| 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);
 | |
| 
 | |
| /* 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. */
 | |
| void BMO_Set_Pnt(struct BMOperator *op, const char *slotname, void *p);
 | |
| void *BMO_Get_Pnt(BMOperator *op, const char *slotname);
 | |
| 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]);
 | |
| 
 | |
| /* 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. */
 | |
| 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]);
 | |
| 
 | |
| void BMO_Clear_Flag_All(BMesh *bm, BMOperator *op, const char htype, int flag);
 | |
| 
 | |
| /* puts every element of type type (which is a bitmask) with tool flag flag,
 | |
|  * into a slot. */
 | |
| void BMO_Flag_To_Slot(struct BMesh *bm, struct BMOperator *op, const char *slotname,
 | |
|                       const int flag, const char htype);
 | |
| 
 | |
| /* tool-flags all elements inside an element slot array with flag flag. */
 | |
| void BMO_Flag_Buffer(struct BMesh *bm, struct BMOperator *op, const char *slotname,
 | |
|                      const int hflag, const char htype);
 | |
| /* clears tool-flag flag from all elements inside a slot array. */
 | |
| void BMO_Unflag_Buffer(struct BMesh *bm, struct BMOperator *op, const char *slotname,
 | |
|                        const int flag, const char htype);
 | |
| 
 | |
| /* tool-flags all elements inside an element slot array with flag flag. */
 | |
| void BMO_HeaderFlag_Buffer(struct BMesh *bm, struct BMOperator *op, const char *slotname,
 | |
|                            const char hflag, const char htype);
 | |
| /* clears tool-flag flag from all elements inside a slot array. */
 | |
| void BMO_UnHeaderFlag_Buffer(struct BMesh *bm, struct BMOperator *op, const char *slotname,
 | |
|                              const char hflag, const char htype);
 | |
| 
 | |
| /* 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).*/
 | |
| void BMO_HeaderFlag_To_Slot(struct BMesh *bm, struct BMOperator *op, const char *slotname,
 | |
|                             const char hflag, const char htype);
 | |
| 
 | |
| /* counts number of elements inside a slot array. */
 | |
| int BMO_CountSlotBuf(struct BMesh *bm, struct BMOperator *op, const char *slotname);
 | |
| int BMO_CountSlotMap(struct BMesh *bm, struct BMOperator *op, const char *slotname);
 | |
| 
 | |
| /* Counts the number of edges with tool flag toolflag around
 | |
|  */
 | |
| int BMO_Vert_CountEdgeFlags(BMesh *bm, BMVert *v, int toolflag);
 | |
| 
 | |
| /* inserts a key/value mapping into a mapping slot.  note that it copies the
 | |
|  * value, it doesn't store a reference to it. */
 | |
| 
 | |
| //BM_INLINE void BMO_Insert_Mapping(BMesh *bm, BMOperator *op, const char *slotname, 
 | |
| 			//void *element, void *data, int len);
 | |
| 
 | |
| /* inserts a key/float mapping pair into a mapping slot. */
 | |
| //BM_INLINE void BMO_Insert_MapFloat(BMesh *bm, BMOperator *op, const char *slotname, 
 | |
| 			//void *element, float val);
 | |
| 
 | |
| //returns 1 if the specified pointer is in the map.
 | |
| //BM_INLINE int BMO_InMap(BMesh *bm, BMOperator *op, const char *slotname, void *element);
 | |
| 
 | |
| /* returns a point to the value of a specific key. */
 | |
| //BM_INLINE void *BMO_Get_MapData(BMesh *bm, BMOperator *op, const char *slotname, void *element);
 | |
| 
 | |
| /* returns the float part of a key/float pair. */
 | |
| //BM_INLINE float BMO_Get_MapFloat(BMesh *bm, BMOperator *op, const char *slotname, void *element);
 | |
| 
 | |
| /* flags all elements in a mapping.  note that the mapping must only have
 | |
|  * bmesh elements in it.*/
 | |
| void BMO_Mapping_To_Flag(struct BMesh *bm, struct BMOperator *op, 
 | |
| 			 const char *slotname, int flag);
 | |
| 
 | |
| /* 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. */
 | |
| 
 | |
| //BM_INLINE void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, const char *slotname, 
 | |
| 			//void *key, void *val);
 | |
| //BM_INLINE void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, const char *slotname,
 | |
| 		       //void *key);
 | |
| 
 | |
| /* 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. */
 | |
| typedef struct BMOIter {
 | |
| 	BMOpSlot *slot;
 | |
| 	int cur; //for arrays
 | |
| 	struct GHashIterator giter;
 | |
| 	void *val;
 | |
| 	char restrictmask; /* bitwise '&' with BMHeader.htype */
 | |
| } BMOIter;
 | |
| 
 | |
| void *BMO_FirstElem(BMOperator *op, const char *slotname);
 | |
| 
 | |
| /* 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).*/
 | |
| void *BMO_IterNew(BMOIter *iter, BMesh *bm, BMOperator *op, 
 | |
|                   const char *slotname, const char restrictmask);
 | |
| void *BMO_IterStep(BMOIter *iter);
 | |
| 
 | |
| /* returns a pointer to the key value when iterating over mappings.
 | |
|  * remember for pointer maps this will be a pointer to a pointer.*/
 | |
| void *BMO_IterMapVal(BMOIter *iter);
 | |
| 
 | |
| /* use this for pointer mappings */
 | |
| void *BMO_IterMapValp(BMOIter *iter);
 | |
| 
 | |
| /* use this for float mappings */
 | |
| float BMO_IterMapValf(BMOIter *iter);
 | |
| 
 | |
| #define BMO_ITER(ele, iter, bm, op, slotname, restrict)  \
 | |
| 	ele = BMO_IterNew(iter, bm, op, slotname, restrict); \
 | |
| 	for ( ; ele; ele=BMO_IterStep(iter))
 | |
| 
 | |
| /******************* Inlined Functions********************/
 | |
| typedef void (*opexec)(struct BMesh *bm, struct BMOperator *op);
 | |
| 
 | |
| /* mappings map elements to data, which
 | |
|  * follows the mapping struct in memory. */
 | |
| typedef struct element_mapping {
 | |
| 	BMHeader *element;
 | |
| 	int len;
 | |
| } element_mapping;
 | |
| 
 | |
| extern const int BMOP_OPSLOT_TYPEINFO[];
 | |
| 
 | |
| BM_INLINE void BMO_Insert_Mapping(BMesh *UNUSED(bm), BMOperator *op, const char *slotname, 
 | |
|                                   void *element, void *data, int len) {
 | |
| 	element_mapping *mapping;
 | |
| 	BMOpSlot *slot = BMO_GetSlot(op, slotname);
 | |
| 
 | |
| 	/*sanity check*/
 | |
| 	if (slot->slottype != BMOP_OPSLOT_MAPPING) return;
 | |
| 	
 | |
| 	mapping = (element_mapping*) BLI_memarena_alloc(op->arena, sizeof(*mapping) + len);
 | |
| 
 | |
| 	mapping->element = (BMHeader*) element;
 | |
| 	mapping->len = len;
 | |
| 	memcpy(mapping+1, data, len);
 | |
| 
 | |
| 	if (!slot->data.ghash) {
 | |
| 		slot->data.ghash = BLI_ghash_new(BLI_ghashutil_ptrhash,
 | |
| 		                                 BLI_ghashutil_ptrcmp, "bmesh op");
 | |
| 	}
 | |
| 	
 | |
| 	BLI_ghash_insert(slot->data.ghash, element, mapping);
 | |
| }
 | |
| 
 | |
| BM_INLINE void BMO_Insert_MapInt(BMesh *bm, BMOperator *op, const char *slotname, 
 | |
|                                  void *element, int val)
 | |
| {
 | |
| 	BMO_Insert_Mapping(bm, op, slotname, element, &val, sizeof(int));
 | |
| }
 | |
| 
 | |
| BM_INLINE void BMO_Insert_MapFloat(BMesh *bm, BMOperator *op, const char *slotname, 
 | |
|                                    void *element, float val)
 | |
| {
 | |
| 	BMO_Insert_Mapping(bm, op, slotname, element, &val, sizeof(float));
 | |
| }
 | |
| 
 | |
| BM_INLINE void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, const char *slotname, 
 | |
|                                      void *element, void *val)
 | |
| {
 | |
| 	BMO_Insert_Mapping(bm, op, slotname, element, &val, sizeof(void*));
 | |
| }
 | |
| 
 | |
| BM_INLINE int BMO_InMap(BMesh *UNUSED(bm), BMOperator *op, const char *slotname, void *element)
 | |
| {
 | |
| 	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);
 | |
| }
 | |
| 
 | |
| BM_INLINE void *BMO_Get_MapData(BMesh *UNUSED(bm), BMOperator *op, const char *slotname,
 | |
|                                 void *element)
 | |
| {
 | |
| 	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;
 | |
| 
 | |
| 	mapping = (element_mapping*) BLI_ghash_lookup(slot->data.ghash, element);
 | |
| 	
 | |
| 	if (!mapping) return NULL;
 | |
| 
 | |
| 	return mapping + 1;
 | |
| }
 | |
| 
 | |
| BM_INLINE float BMO_Get_MapFloat(BMesh *bm, BMOperator *op, const char *slotname,
 | |
|                                  void *element)
 | |
| {
 | |
| 	float *val = (float*) BMO_Get_MapData(bm, op, slotname, element);
 | |
| 	if (val) return *val;
 | |
| 
 | |
| 	return 0.0f;
 | |
| }
 | |
| 
 | |
| BM_INLINE int BMO_Get_MapInt(BMesh *bm, BMOperator *op, const char *slotname,
 | |
|                              void *element)
 | |
| {
 | |
| 	int *val = (int*) BMO_Get_MapData(bm, op, slotname, element);
 | |
| 	if (val) return *val;
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| BM_INLINE void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, const char *slotname,
 | |
|                                    void *element)
 | |
| {
 | |
| 	void **val = (void**) BMO_Get_MapData(bm, op, slotname, element);
 | |
| 	if (val) return *val;
 | |
| 
 | |
| 	return NULL;
 | |
| }
 | |
| 
 | |
| BM_INLINE void BMO_SetIndex(BMesh *bm, const void *element, int index)
 | |
| {
 | |
| 	BMHeader *header = (BMHeader *)element;
 | |
| 	header->flags[bm->stackdepth-1].index = index;
 | |
| }
 | |
| 
 | |
| BM_INLINE int BMO_GetIndex(BMesh *bm, void *element)
 | |
| {
 | |
| 	BMHeader *header = (BMHeader *)element;
 | |
| 	return header->flags[bm->stackdepth-1].index;
 | |
| }
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #endif /* _BMESH_OPERATOR_API_H */
 |