<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
-- Version="9,00"\r
++ Version="9.00"\r
Name="ED_editors"\r
ProjectGUID="{FB88301F-F725-401B-ACD7-D2ABBF333B71}"\r
RootNamespace="BL_editors"\r
<Filter\r
Name="mesh"\r
>\r
++ <File\r
++ RelativePath="..\..\..\source\blender\editors\mesh\bmeshutils.c"\r
++ >\r
++ </File>\r
<File\r
RelativePath="..\..\..\source\blender\editors\mesh\editdeform.c"\r
>\r
return d;
}
-
++/*original function from shadeoutput.c*/
+double Normalize_d(double *n)
+{
+ double d;
+
+ d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2];
- /* A larger value causes normalize errors in a scaled down models with camera xtreme close */
- if(d>1.0e-35F) {
++
++ if(d>0.00000000000000001) {
+ d= sqrt(d);
+
+ n[0]/=d;
+ n[1]/=d;
+ n[2]/=d;
+ } else {
+ n[0]=n[1]=n[2]= 0.0;
+ d= 0.0;
+ }
+ return d;
+}
+
void Crossf(float *c, float *a, float *b)
{
c[0] = a[1] * b[2] - a[2] * b[1];
--- /dev/null
+#ifndef BM_OPERATORS_H
+#define BM_OPERATORS_H
+
+#include "BLI_memarena.h"
+#include "BLI_ghash.h"
+
+#include <stdarg.h>
+
+#define BMOP_OPSLOT_INT 0
+#define BMOP_OPSLOT_FLT 1
+#define BMOP_OPSLOT_PNT 2
+#define BMOP_OPSLOT_VEC 6
+
+/*after BMOP_OPSLOT_VEC, everything is
+ dynamically allocated arrays. we
+ leave a space in the identifiers
+ for future growth.*/
+#define BMOP_OPSLOT_PNT_BUF 7
+
+#define BMOP_OPSLOT_MAPPING 8
+#define BMOP_OPSLOT_TYPES 9
+
+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]; /*vector*/
+ void *buf; /*buffer*/
+ GHash *ghash;
+ } data;
+}BMOpSlot;
+
+/*BMOpSlot->flag*/
+/*is a dynamically-allocated array. set at runtime.*/
+#define BMOS_DYNAMIC_ARRAY 1
+
+/*operators represent logical, executable mesh modules.*/
+#define BMOP_MAX_SLOTS 16 /*way more than probably needed*/
+
+typedef struct BMOperator{
+ int type;
+ int slottype;
+ int needflag;
+ 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;
+
+/*need to refactor code to use this*/
+typedef struct BMOpDefine {
+ char *name;
+ slottype slottypes[BMOP_MAX_SLOTS];
+ void (*exec)(BMesh *bm, BMOperator *op);
+ int totslot;
+ int flag;
+} BMOpDefine;
+
+/*BMOpDefine->flag*/
+//doesn't do anything at the moment.
+
+/*API for operators*/
+
+/*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 BMOperator *op, int opcode);
+void BMO_Exec_Op(struct BMesh *bm, struct BMOperator *op);
+void BMO_Finish_Op(struct BMesh *bm, struct BMOperator *op);
+BMOpSlot *BMO_GetSlot(struct BMOperator *op, int slotcode);
+void BMO_CopySlot(struct BMOperator *source_op, struct BMOperator *dest_op, int src, int dst);
+void BMO_Set_Float(struct BMOperator *op, int slotcode, float f);
+void BMO_Set_Int(struct BMOperator *op, int slotcode, int i);
+void BMO_Set_Pnt(struct BMOperator *op, int slotcode, void *p);
+void BMO_Set_Vec(struct BMOperator *op, int slotcode, float *vec);
+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);
+int BMO_CountFlag(struct BMesh *bm, int flag, int type);
+void BMO_Flag_To_Slot(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag, int type);
+void BMO_Flag_Buffer(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag);
+void BMO_Unflag_Buffer(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag);
+void BMO_HeaderFlag_To_Slot(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag, int type);
+int BMO_CountSlotBuf(struct BMesh *bm, struct BMOperator *op, int slotcode);
+
+/*copies data, doesn't store a reference to it.*/
+void BMO_Insert_Mapping(BMesh *bm, BMOperator *op, int slotcode,
+ void *element, void *data, int len);
+void BMO_Insert_MapFloat(BMesh *bm, BMOperator *op, int slotcode,
+ void *element, float val);
+
+//returns 1 if the specified element is in the map.
+int BMO_InMap(BMesh *bm, BMOperator *op, int slotcode, void *element);
+void *BMO_Get_MapData(BMesh *bm, BMOperator *op, int slotcode,
+ void *element);
+float BMO_Get_MapFloat(BMesh *bm, BMOperator *op, int slotcode,
+ void *element);
+void BMO_Mapping_To_Flag(struct BMesh *bm, struct BMOperator *op,
+ int slotcode, int flag);
+
+/*do NOT use these for non-operator-api-allocated memory! instead
+ use BMO_Get_MapData, which copies the data.*/
+void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, int slotcode,
+ void *element, void *val);
+void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, int slotcode,
+ void *element);
+
+struct GHashIterator;
+typedef struct BMOIter {
+ BMOpSlot *slot;
+ int cur; //for arrays
+ struct GHashIterator giter;
+ void *val;
+} BMOIter;
+
+void *BMO_IterNew(BMOIter *iter, BMesh *bm, BMOperator *op,
+ int slotcode);
+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);
+
+/*formatted operator initialization/execution*/
+int BMO_CallOpf(BMesh *bm, char *fmt, ...);
+int BMO_InitOpf(BMesh *bm, BMOperator *op, char *fmt, ...);
+int BMO_VInitOpf(BMesh *bm, BMOperator *op, char *fmt, va_list vlist);
+
+/*----------- bmop error system ----------*/
+
+/*pushes an error onto the bmesh error stack.
+ if msg is null, then the default message for the errorcode is used.*/
+void BMO_RaiseError(BMesh *bm, BMOperator *owner, int errcode, char *msg);
+
+/*gets the topmost error from the stack.
+ returns error code or 0 if no error.*/
+int BMO_GetError(BMesh *bm, char **msg, BMOperator **op);
+
+/*same as geterror, only pops the error off the stack as well*/
+int BMO_PopError(BMesh *bm, char **msg, BMOperator **op);
+void BMO_ClearStack(BMesh *bm);
+
+#if 0
+//this is meant for handling errors, like self-intersection test failures.
+//it's dangerous to handle errors in general though, so disabled for now.
+
+/*catches an error raised by the op pointed to by catchop.
+ errorcode is either the errorcode, or BMERR_ALL for any
+ error.*/
+int BMO_CatchOpError(BMesh *bm, BMOperator *catchop, int errorcode, char **msg);
+#endif
+
+/*------ error code defines -------*/
+
+/*error messages*/
+#define BMERR_SELF_INTERSECTING 1
+#define BMERR_DISSOLVEDISK_FAILED 2
+#define BMERR_CONNECTVERT_FAILED 3
++#define BMERR_WALKER_FAILED 4
+
+static char *bmop_error_messages[] = {
+ 0,
+ "Self intersection error",
+ "Could not dissolve vert",
+ "Could not connect verts",
++ "Could not traverse mesh",
+};
+
+/*------------begin operator defines (see bmesh_opdefines.c too)------------*/
+/*split op*/
+#define BMOP_SPLIT 0
+
+enum {
+ BMOP_SPLIT_MULTIN,
+ BMOP_SPLIT_MULTOUT,
+ BMOP_SPLIT_BOUNDS_EDGEMAP, //bounding edges of split faces
+ BMOP_SPLIT_TOTSLOT,
+};
+
+/*dupe op*/
+#define BMOP_DUPE 1
+
+enum {
+ BMOP_DUPE_MULTIN,
+ BMOP_DUPE_ORIG,
+ BMOP_DUPE_NEW,
+ /*we need a map for verts duplicated not connected
+ to any faces, too.*/
+ BMOP_DUPE_BOUNDS_EDGEMAP,
+ BMOP_DUPE_TOTSLOT
+};
+
+/*delete op*/
+#define BMOP_DEL 2
+
+enum {
+ BMOP_DEL_MULTIN,
+ BMOP_DEL_CONTEXT,
+ BMOP_DEL_TOTSLOT,
+};
+
+#define DEL_VERTS 1
+#define DEL_EDGES 2
+#define DEL_ONLYFACES 3
+#define DEL_EDGESFACES 4
+#define DEL_FACES 5
+#define DEL_ALL 6
+#define DEL_ONLYTAGGED 7
+
+/*BMOP_DEL_CONTEXT*/
+enum {
+ BMOP_DEL_VERTS = 1,
+ BMOP_DEL_EDGESFACES,
+ BMOP_DEL_ONLYFACES,
+ BMOP_DEL_FACES,
+ BMOP_DEL_ALL,
+};
+
+/*editmesh->bmesh op*/
+#define BMOP_FROM_EDITMESH 3
+enum {
+ BMOP_FROM_EDITMESH_EM,
+ BMOP_FROM_EDITMESH_TOTSLOT,
+};
+
+#define BMOP_TO_EDITMESH 4
+/*bmesh->editmesh op*/
+enum {
+ BMOP_TO_EDITMESH_EMOUT,
+ BMOP_TO_EDITMESH_TOTSLOT,
+};
+
+/*edge subdivide op*/
+#define BMOP_ESUBDIVIDE 5
+enum {
+ BMOP_ESUBDIVIDE_EDGES,
+ BMOP_ESUBDIVIDE_NUMCUTS,
+ BMOP_ESUBDIVIDE_FLAG, //beauty flag in esubdivide
+ BMOP_ESUBDIVIDE_RADIUS,
+
+ BMOP_ESUBDIVIDE_CUSTOMFILL_FACEMAP,
+ BMOP_ESUBDIVIDE_PERCENT_EDGEMAP,
+
+ /*inner verts/new faces of completely filled faces, e.g.
+ fully selected face.*/
+ BMOP_ESUBDIVIDE_INNER_MULTOUT,
+
+ /*new edges and vertices from splitting original edges,
+ doesn't include edges creating by connecting verts.*/
+ BMOP_ESUBDIVIDE_SPLIT_MULTOUT,
+ BMOP_ESUBDIVIDE_TOTSLOT,
+};
+/*
+SUBDIV_SELECT_INNER
+SUBDIV_SELECT_ORIG
+SUBDIV_SELECT_INNER_SEL
+SUBDIV_SELECT_LOOPCUT
+DOUBLEOPFILL
+*/
+
+/*triangulate*/
+#define BMOP_TRIANGULATE 6
+
+enum {
+ BMOP_TRIANG_FACEIN,
+ BMOP_TRIANG_NEW_EDGES,
+ BMOP_TRIANG_NEW_FACES,
+ BMOP_TRIANG_TOTSLOT,
+};
+
+/*dissolve faces*/
+#define BMOP_DISSOLVE_FACES 7
+enum {
+ BMOP_DISFACES_FACEIN,
+ //list of faces that comprise regions of split faces
+ BMOP_DISFACES_REGIONOUT,
+ BMOP_DISFACES_TOTSLOT,
+};
+
+/*dissolve verts*/
+#define BMOP_DISSOLVE_VERTS 8
+
+enum {
+ BMOP_DISVERTS_VERTIN,
+ BMOP_DISVERTS_TOTSLOT,
+};
+
+#define BMOP_MAKE_FGONS 9
+#define BMOP_MAKE_FGONS_TOTSLOT 0
+
+#define BMOP_EXTRUDE_EDGECONTEXT 10
+enum {
+ BMOP_EXFACE_EDGEFACEIN,
+ BMOP_EXFACE_EXCLUDEMAP, //exclude edges from skirt connecting
+ BMOP_EXFACE_MULTOUT, //new geometry
+ BMOP_EXFACE_TOTSLOT,
+};
+
+#define BMOP_CONNECT_VERTS 11
+enum {
+ BM_CONVERTS_VERTIN,
+ BM_CONVERTS_EDGEOUT,
+ BM_CONVERTS_TOTSLOT
+};
+
+/*keep this updated!*/
+#define BMOP_TOTAL_OPS 12
+/*-------------------------------end operator defines-------------------------------*/
+
+extern BMOpDefine *opdefines[];
+extern int bmesh_total_ops;
+
+/*------specific operator helper functions-------*/
+
+/*executes the duplicate operation, feeding elements of
+ type flag etypeflag and header flag flag to it. note,
+ to get more useful information (such as the mapping from
+ original to new elements) you should run the dupe op manually.*/
+struct Object;
+struct EditMesh;
+
+void BMOP_DupeFromFlag(struct BMesh *bm, int etypeflag, int flag);
+void BM_esubdivideflag(struct Object *obedit, struct BMesh *bm, int selflag, float rad,
+ int flag, int numcuts, int seltype);
+void BM_extrudefaceflag(BMesh *bm, int flag);
+
+/*these next two return 1 if they did anything, or zero otherwise.
+ they're kindof a hackish way to integrate with fkey, until
+ such time as fkey is completely bmeshafied.*/
+int BM_DissolveFaces(struct EditMesh *em, int flag);
+/*this doesn't display errors to the user, btw*/
+int BM_ConnectVerts(struct EditMesh *em, int flag);
+
+#endif
--- /dev/null
- void (*step) (struct BMWalker *walker);
- int visitedmask;
+#ifndef BM_WALKERS_H
+#define BM_WALKERS_H
+
++#include "BLI_ghash.h"
++
++/*
++ NOTE: do NOT modify topology while walking a mesh!
++*/
++
+/*Walkers*/
+typedef struct BMWalker{
+ BLI_mempool *stack;
+ BMesh *bm;
+ void *currentstate;
+ void *(*begin) (struct BMWalker *walker, void *start);
+ void *(*yield)(struct BMWalker *walker);
- void BMWalker_Init(struct BMWalker *walker, BMesh *bm, int type, int searchmask);
++ void *(*step) (struct BMWalker *walker);
+ int restrictflag;
++ GHash *visithash;
+}BMWalker;
+
- #define BM_SHELLWALKER 0
- #define BM_LOOPWALKER 1
- #define BM_RINGWALKER 2
- #define BM_UVISLANDS 3
- #define BM_MAXWALKERS 4
++void BMWalker_Init(struct BMWalker *walker,BMesh *bm,int type, int searchmask);
+void *BMWalker_Step(struct BMWalker *walker);
+void BMWalker_End(struct BMWalker *walker);
+
++#define BMW_SHELL 0
++/*#define BMW_LOOP 1
++#define BMW_RING 2
++#define BMW_UVISLANDS 3*/
++#define BMW_ISLANDBOUND 1
++#define BMW_MAXWALKERS 2
+
+#endif
--- /dev/null
- /*
+#include <stdio.h>
+#include <string.h>
+#include "BLI_mempool.h"
+
+#include "bmesh_private.h"
+#include "bmesh_walkers.h"
+
+#include "bmesh.h"
+
++/*
++ - joeedh -
++ design notes:
++
++ * walkers should use tool flags, not header flags
++ * walkers now use ghash rather then stealing flags.
++ ghash can be rewritten to be faster if necassary.
++ * walkers should always raise BMERR_WALKER_FAILED,
++ with a custom error message.
++ * tools should ALWAYS have necassary error handling
++ for if walkers fail.
++*/
++
+/*
+NOTE: This code needs to be read through a couple of times!!
+*/
+
+typedef struct shellWalker{
+ struct shellWalker *prev;
+ BMVert *base;
+ BMEdge *curedge, *current;
+} shellWalker;
+
- static int request_walkerMask(struct BMesh *bm);
++typedef struct islandboundWalker {
++ struct islandboundWalker *prev;
++ BMEdge *base;
++ BMVert *lastv;
++ BMEdge *curedge;
++} islandboundWalker;
++
++/* NOTE: this comment is out of date, update it - joeedh
+ * BMWalker - change this to use the filters functions.
+ *
+ * A generic structure for maintaing the state and callbacks nessecary for walking over
+ * the surface of a mesh. An example of usage:
+ *
+ * BMEdge *edge;
+ * BMWalker *walker = BMWalker_create(BM_SHELLWALKER, BM_SELECT);
+ * walker->begin(walker, vert);
+ * for(edge = BMWalker_walk(walker); edge; edge = bmeshWwalker_walk(walker)){
+ * bmesh_select_edge(edge);
+ * }
+ * BMWalker_free(walker);
+ *
+ * The above example creates a walker that walks over the surface a mesh by starting at
+ * a vertex and traveling across its edges to other vertices, and repeating the process
+ * over and over again until it has visited each vertex in the shell. An additional restriction
+ * is passed into the BMWalker_create function stating that we are only interested
+ * in walking over edges that have been flagged with the bitmask 'BM_SELECT'.
+ *
+ *
+*/
+
+/*Forward declerations*/
- static void BMWalker_popState(struct BMWalker *walker);
- static void BMWalker_pushState(struct BMWalker *walker);
- static void *shellWalker_begin(struct BMWalker *walker, void *data);
- static void *shellWalker_yield(struct BMWalker *walker);
- static void shellWalker_step(struct BMWalker *walker);
+static void *BMWalker_walk(struct BMWalker *walker);
- /*
- * REQUEST_WALKERMASK
- *
- * Each active walker for a bmesh has its own bitmask
- * to use for flagging elements as visited. request_walkerMask
- * queries the bmesh passed in and returns the first free
- * bitmask. If none are free, it returns 0. The maximum number
- * of walkers that can be used for a single bmesh between calls to
- * bmesh_edit_begin() and bmesh_edit_end() is defined by the constant
- * BM_MAXWALKERS.
- *
- */
-
- static int request_walkerMask(BMesh *bm)
- {
- int i;
- for(i=0; i < BM_MAXWALKERS; i++){
- if(!(bm->walkers & (1 << i))){
- bm->walkers |= (1 << i);
- return (1 << i);
- }
- }
- return 0;
- }
-
-
-
-
++static void BMWalker_popstate(struct BMWalker *walker);
++static void BMWalker_pushstate(struct BMWalker *walker);
++
++static void *shellWalker_Begin(struct BMWalker *walker, void *data);
++static void *shellWalker_Yield(struct BMWalker *walker);
++static void *shellWalker_Step(struct BMWalker *walker);
++
++static void *islandboundWalker_Begin(BMWalker *walker, void *data);
++static void *islandboundWalker_Yield(BMWalker *walker);
++static void *islandboundWalker_Step(BMWalker *walker);
++
+struct shellWalker;
+
+/* Pointer hiding*/
+typedef struct bmesh_walkerGeneric{
+ struct bmesh_walkerGeneric *prev;
+} bmesh_walkerGeneric;
+
+
- void BMWalker_init(BMWalker *walker, BMesh *bm, int type, int searchmask)
+/*
+ * BMWalker_CREATE
+ *
+ * Allocates and returns a new mesh walker of
+ * a given type. The elements visited are filtered
+ * by the bitmask 'searchmask'.
+ *
+*/
+
- int visitedmask = request_walkerMask(bm);
++void BMWalker_Init(BMWalker *walker, BMesh *bm, int type, int searchmask)
+{
- if(visitedmask){
- memset(walker, 0, sizeof(BMWalker));
- walker->bm = bm;
- walker->visitedmask = visitedmask;
- walker->restrictflag = searchmask;
- switch(type){
- case BM_SHELLWALKER:
- walker->begin = shellWalker_begin;
- walker->step = shellWalker_step;
- walker->yield = shellWalker_yield;
- size = sizeof(shellWalker);
- break;
- //case BM_LOOPWALKER:
- // walker->begin = loopwalker_begin;
- // walker->step = loopwalker_step;
- // walker->yield = loopwalker_yield;
- // size = sizeof(loopWalker);
- // break;
- //case BM_RINGWALKER:
- // walker->begin = ringwalker_begin;
- // walker->step = ringwalker_step;
- // walker->yield = ringwalker_yield;
- // size = sizeof(ringWalker);
- // break;
- default:
- break;
- }
- walker->stack = BLI_mempool_create(size, 100, 100);
- walker->currentstate = NULL;
+ int size = 0;
+
- * BMWalker_END
++ memset(walker, 0, sizeof(BMWalker));
++ walker->bm = bm;
++ walker->restrictflag = searchmask;
++ walker->visithash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
++
++ switch(type){
++ case BMW_SHELL:
++ walker->begin = shellWalker_Begin;
++ walker->step = shellWalker_Step;
++ walker->yield = shellWalker_Yield;
++ size = sizeof(shellWalker);
++ break;
++ case BMW_ISLANDBOUND:
++ walker->begin = islandboundWalker_Begin;
++ walker->step = islandboundWalker_Step;
++ walker->yield = islandboundWalker_Yield;
++ size = sizeof(islandboundWalker);
++ break;
++ //case BMW_LOOP:
++ // walker->begin = loopwalker_Begin;
++ // walker->step = loopwalker_Step;
++ // walker->yield = loopwalker_Yield;
++ // size = sizeof(loopWalker);
++ // break;
++ //case BMW_RING:
++ // walker->begin = ringwalker_Begin;
++ // walker->step = ringwalker_Step;
++ // walker->yield = ringwalker_Yield;
++ // size = sizeof(ringWalker);
++ // break;
++ default:
++ break;
+ }
++ walker->stack = BLI_mempool_create(size, 100, 100);
++ walker->currentstate = NULL;
+}
+
+/*
- void BMWalker_end(BMWalker *walker)
++ * BMWalker_End
+ *
+ * Frees a walker's stack.
+ *
+*/
+
- * BMWalker_STEP
++void BMWalker_End(BMWalker *walker)
+{
+ BLI_mempool_destroy(walker->stack);
+}
+
+
+/*
- void *BMWalker_step(BMWalker *walker)
++ * BMWalker_Step
+ *
+*/
+
- while(head = BMWalker_walk(walker)){
- //NOTE: figure this out
- //if(bmesh_test_flag(head, walker->restrictflag)) return head;
- return head;
- }
- return NULL;
++void *BMWalker_Step(BMWalker *walker)
+{
+ BMHeader *head;
+
- else BMWalker_popState(walker);
++ head = BMWalker_walk(walker);
++
++ return head;
+}
+
+/*
+ * BMWalker_WALK
+ *
+ * Steps a mesh walker forward by one element
+ *
+ * TODO:
+ * -add searchmask filtering
+ *
+*/
+
+static void *BMWalker_walk(BMWalker *walker)
+{
+ void *current = NULL;
+
+ while(walker->currentstate){
+ walker->step(walker);
+ current = walker->yield(walker);
+ if(current) return current;
- * BMWalker_POPSTATE
++ else BMWalker_popstate(walker);
+
+ }
+ return NULL;
+}
+
+/*
- static void BMWalker_popState(BMWalker *walker)
++ * BMWalker_popstate
+ *
+ * Pops the current walker state off the stack
+ * and makes the previous state current
+ *
+*/
+
- * BMWalker_PUSHSTATE
++static void BMWalker_popstate(BMWalker *walker)
+{
+ void *oldstate;
+ oldstate = walker->currentstate;
+ walker->currentstate
+ = ((bmesh_walkerGeneric*)walker->currentstate)->prev;
+ BLI_mempool_free(walker->stack, oldstate);
+}
+
+/*
- static void BMWalker_pushState(BMWalker *walker)
++ * BMWalker_pushstate
+ *
+ * Pushes the current state down the stack and allocates
+ * a new one.
+ *
+*/
+
- static void *shellWalker_begin(BMWalker *walker, void *data){
++static void BMWalker_pushstate(BMWalker *walker)
+{
+ bmesh_walkerGeneric *newstate;
+ newstate = BLI_mempool_alloc(walker->stack);
+ newstate->prev = walker->currentstate;
+ walker->currentstate = newstate;
+}
+
+/* Shell Walker:
+ *
+ * Starts at a vertex on the mesh and walks over the 'shell' it belongs
+ * to via visiting connected edges.
+ *
+ * TODO:
+ *
+ * Add restriction flag/callback for wire edges.
+ *
+*/
+
- BMWalker_pushState(walker);
++static void *shellWalker_Begin(BMWalker *walker, void *data){
+ BMVert *v = data;
+ shellWalker *shellWalk = NULL;
- shellWalk->base = shellWalk->curedge = NULL;
++ BMWalker_pushstate(walker);
+ shellWalk = walker->currentstate;
- static void *shellWalker_yield(BMWalker *walker)
++ shellWalk->base = NULL;
++ shellWalk->curedge = NULL;
+ if(v->edge){
+ shellWalk->base = v;
+ shellWalk->curedge = v->edge;
+ }
++
++ return v->edge;
+}
- static void shellWalker_step(BMWalker *walker)
++static void *shellWalker_Yield(BMWalker *walker)
+{
+ shellWalker *shellWalk = walker->currentstate;
+ return shellWalk->curedge;
+}
+
-
- if(!(shellWalk->base->head.flag & walker->visitedmask))
- shellWalk->base->head.flag |= walker->visitedmask;
++static void *shellWalker_Step(BMWalker *walker)
+{
+ BMEdge *curedge, *next = NULL;
+ BMVert *ov = NULL;
+ int restrictpass = 1;
+ shellWalker *shellWalk = walker->currentstate;
- if(!(curedge->head.flag & walker->visitedmask)){
- curedge->head.flag |= walker->visitedmask;
- if(walker->restrictflag && (!(curedge->head.flag & walker->restrictflag))) restrictpass = 0;
- if(restrictpass){
+
++ if (!BLI_ghash_lookup(walker->visithash, shellWalk->base))
++ BLI_ghash_insert(walker->visithash, shellWalk->base, NULL);
++
+ /*find the next edge whose other vertex has not been visited*/
+ curedge = shellWalk->curedge;
+ do{
- BMWalker_pushState(walker);
++ if (!BLI_ghash_lookup(walker->visithash, curedge)) {
++ BLI_ghash_insert(walker->visithash, curedge, NULL);
++ if(walker->restrictflag && (!BMO_TestFlag(walker->bm, curedge, walker->restrictflag))) restrictpass = 0;
++ if(restrictpass) {
+ ov = BM_OtherEdgeVert(curedge, shellWalk->base);
+
+ /*save current state*/
+ shellWalk->curedge = curedge;
+ /*push a new state onto the stack*/
- }
++ BMWalker_pushstate(walker);
+
+ /*populate the new state*/
+ ((shellWalker*)walker->currentstate)->base = ov;
+ ((shellWalker*)walker->currentstate)->curedge = curedge;
+ /*break out of loop*/
+
+ next = curedge;
+ break;
+ }
+ curedge = bmesh_disk_nextedge(curedge, shellWalk->base);
+ }
+ }while(curedge != shellWalk->curedge);
+
+ shellWalk->current = next;
+ return shellWalk->current;
++}
++
++/* Island Boundary Walker:
++ *
++ * Starts at a edge on the mesh and walks over the boundary of an
++ * island it belongs to.
++ *
++ * TODO:
++ *
++ * Add restriction flag/callback for wire edges.
++ *
++*/
++
++static void *islandboundWalker_Begin(BMWalker *walker, void *data){
++ BMEdge *e = data;
++ islandboundWalker *iwalk = NULL;
++
++ BMWalker_pushstate(walker);
++
++ iwalk = walker->currentstate;
++ iwalk->base = iwalk->curedge = e;
++
++ return e;
++}
++
++static void *islandboundWalker_Yield(BMWalker *walker)
++{
++ islandboundWalker *iwalk = walker->currentstate;
++
++ return iwalk->curedge;
++}
++
++static void *islandboundWalker_Step(BMWalker *walker)
++{
++ islandboundWalker *iwalk = walker->currentstate, *owalk;
++ BMIter iter;
++ BMVert *v;
++ BMEdge *e = iwalk->curedge;
++ int found;
++
++ owalk = iwalk;
++
++ if (iwalk->lastv == e->v1) v = e->v2;
++ else v = e->v1;
++
++ BMWalker_popstate(walker);
++
++ e=BMIter_New(&iter, walker->bm, BM_EDGES_OF_VERT, v);
++ for (; e; e=BMIter_Step(&iter)) {
++ if (!BMO_TestFlag(walker->bm, e, walker->restrictflag))
++ continue;
++ if (BLI_ghash_haskey(walker->visithash, e)) continue;
++
++ BLI_ghash_insert(walker->visithash, e, NULL);
++ BMWalker_pushstate(walker);
++
++ iwalk = walker->currentstate;
++ iwalk->base = iwalk->base;
++ iwalk->curedge = e;
++ iwalk->lastv = v;
++
++ }
++
++ return iwalk->curedge;
++}
if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'):
targetdir = '#' + targetdir
++ #root_build_dir = "#"
makesdna = makesdna_tool.Program (target = targetdir, source = source_files, LIBS=['bf_guardedalloc'])
dna_dict = dna.Dictionary()
dna.Depends ('dna.c', makesdna)
dna.Depends ('dna.c', header_files)
++
++ap = os.path.abspath
++
if env['OURPLATFORM'] != 'linuxcross':
if USE_WINE:
-- dna.Command ('dna.c', '', 'wine ' + root_build_dir+os.sep+"makesdna $TARGET")
++ dna.Command ('dna.c', '', 'wine ' + ap(root_build_dir+os.sep+"makesdna $TARGET"))
else:
-- dna.Command ('dna.c', '', root_build_dir+os.sep+"makesdna $TARGET")
++ dna.Command ('dna.c', '', ap(root_build_dir+os.sep+"makesdna $TARGET"))
else:
-- dna.Command ('dna.c', '', root_build_dir+os.sep+"makesdna.exe $TARGET")
++ dna.Command ('dna.c', '', ap(root_build_dir+os.sep+"makesdna.exe $TARGET"))
obj = ['intern/dna.c', 'intern/dna_genfile.c']
Return ('obj')
import sys
import os
++ap = os.path.abspath
++
Import ('env')
cflags = '-Wall'
defines = []
--root_build_dir=env['BF_BUILDDIR']
++root_build_dir=ap(env['BF_BUILDDIR'])
source_files = env.Glob('*.c')
rna.Depends (generated_files, makesrna)
# this seems bad, how to retrieve it from scons?
--build_dir = root_build_dir + '/source/blender/makesrna/intern/'
++build_dir = ap(root_build_dir + '/source/blender/makesrna/intern') + "/"
if env['OURPLATFORM'] != 'linuxcross':
-- rna.Command (generated_files, '', root_build_dir+os.sep+"makesrna " + build_dir)
++ rna.Command (generated_files, '', ap(root_build_dir+os.sep+"makesrna ") + " \"" + build_dir + "\"")
else:
-- rna.Command (generated_files, '', root_build_dir+os.sep+"makesrna.exe " + build_dir)
++ rna.Command (generated_files, '', ap(root_build_dir+os.sep+"makesrna.exe") + " \"" + build_dir + "\"")
if USE_WINE:
-- rna.Command (generated_files, '', 'wine ' + root_build_dir+os.sep+"makesrna.exe " + build_dir)
++ rna.Command (generated_files, '', ap('wine ' + root_build_dir+os.sep+"makesrna.exe") + " \"" + build_dir + "\"")
else:
-- rna.Command (generated_files, '', root_build_dir+os.sep+"makesrna.exe " + build_dir)
++ rna.Command (generated_files, '', ap(root_build_dir+os.sep+"makesrna.exe") + " \"" + build_dir + "\"")
obj = ['intern/rna_access.c', 'intern/rna_dependency.c']
/* ---------------- shaders ----------------------- */
--static double Normalize_d(double *n)
--{
-- double d;
--
-- d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2];
--
-- if(d>0.00000000000000001) {
-- d= sqrt(d);
--
-- n[0]/=d;
-- n[1]/=d;
-- n[2]/=d;
-- } else {
-- n[0]=n[1]=n[2]= 0.0;
-- d= 0.0;
-- }
-- return d;
--}
--
/* mix of 'real' fresnel and allowing control. grad defines blending gradient */
float fresnel_fac(float *view, float *vn, float grad, float fac)
{