﻿<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>https://wiki.blender.jp/index.php?action=history&amp;feed=atom&amp;title=%E5%88%A9%E7%94%A8%E8%80%85%3AIdeasman42%2FBMeshBranchReview</id>
	<title>利用者:Ideasman42/BMeshBranchReview - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.blender.jp/index.php?action=history&amp;feed=atom&amp;title=%E5%88%A9%E7%94%A8%E8%80%85%3AIdeasman42%2FBMeshBranchReview"/>
	<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=%E5%88%A9%E7%94%A8%E8%80%85:Ideasman42/BMeshBranchReview&amp;action=history"/>
	<updated>2026-06-13T20:03:03Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.31.0</generator>
	<entry>
		<id>https://wiki.blender.jp/index.php?title=%E5%88%A9%E7%94%A8%E8%80%85:Ideasman42/BMeshBranchReview&amp;diff=105225&amp;oldid=prev</id>
		<title>Yamyam: 1版 をインポートしました</title>
		<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=%E5%88%A9%E7%94%A8%E8%80%85:Ideasman42/BMeshBranchReview&amp;diff=105225&amp;oldid=prev"/>
		<updated>2018-06-28T19:43:37Z</updated>

		<summary type="html">&lt;p&gt;1版 をインポートしました&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ja&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← 古い版&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;2018年6月28日 (木) 19:43時点における版&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;ja&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(相違点なし)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Yamyam</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.blender.jp/index.php?title=%E5%88%A9%E7%94%A8%E8%80%85:Ideasman42/BMeshBranchReview&amp;diff=105224&amp;oldid=prev</id>
		<title>wiki&gt;Ideasman42: /* Update 43694 */</title>
		<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=%E5%88%A9%E7%94%A8%E8%80%85:Ideasman42/BMeshBranchReview&amp;diff=105224&amp;oldid=prev"/>
		<updated>2012-01-25T20:16:13Z</updated>

		<summary type="html">&lt;p&gt;‎&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Update 43694&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= BMesh Branch Review =&lt;br /&gt;
As of 36634.&lt;br /&gt;
== Summery ==&lt;br /&gt;
First of all, BMesh has many TODO's - see:&amp;lt;br&amp;gt;http://wiki.blender.org/index.php/Dev:2.5/Source/Development/Todo/BMesh&lt;br /&gt;
&lt;br /&gt;
Aside from those, this is my opinion regarding the status of BMesh and the main things that should be resolved before merging.&lt;br /&gt;
&lt;br /&gt;
* The BMesh API is generally fine however I don't think the BMO operator API should be so high level (details below), appreciate feedback from other developers here.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;s&amp;gt;BMesh data structures need cleaning (~1.7x memory usage compared to trunk)&amp;lt;br&amp;gt;looks like some members were added for single uses, would like to see this refined, remove unused members and remove members which were added for one off usage (where allocating an array for example can replace having these struct members), memory usage will still grow but best not be wasteful.&amp;lt;/s&amp;gt;&amp;lt;br&amp;gt;''Edit, Joe removed some members, usage is now ~1.5x.''&lt;br /&gt;
&lt;br /&gt;
* BMesh is much slower at deforming subsurf, approx 2-3x overall slower. Should be resolved before merging.&lt;br /&gt;
&lt;br /&gt;
--[[User:Ideasman42|Ideasman42]] 09:25, 12 May 2011 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Changes that should be reviewed separately ==&lt;br /&gt;
&lt;br /&gt;
Where these features are not essential they could be removed from the BMesh branch and made into patches, or merged into trunk if the module owner is ok with it.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;s&amp;gt;MEM_guardedalloc has its MemHead struct made public, adds function WMEM_freeN which is only used once in bmesh_tools.c. Otherwise trunk's MEM_ source works fine in BMesh, so need to see if this is worth merging.&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;s&amp;gt;GHOST C API adds GHOST_RecordEvents(), GHOST_StopRecording(), GHOST_PlaybackEvents(). Event recording seems completely separated from bmesh.&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* shape keys have an added Key-&amp;gt;uidgen, Custom data layers &amp;amp; KeyBlock added a 'uid', seems unrelated to bmesh, what does this solve?&lt;br /&gt;
&lt;br /&gt;
== Style Suggestions ==&lt;br /&gt;
==== BM_TestHFlag ====&lt;br /&gt;
Macro BM_TestHFlag() includes a NULL check, IMHO this encourages defensive programming where there are NULL checks when really the developer should know when a variable is NULL and account for it explicitly, in a way others know the expected state, also means macros that don't have NULL check will crash anyway.&lt;br /&gt;
&lt;br /&gt;
==== Selection checking ====&lt;br /&gt;
Selection and hidden states are both checked, in 2.4x there is a convention that if something is selected, then it cant be hidden, I think this is a good convention to keep, so unless theres a good reason to support this, could lines...&lt;br /&gt;
 if(!BM_TestHFlag(eve, BM_HIDDEN) &amp;amp;&amp;amp; BM_TestHFlag(eve, BM_SELECT))&lt;br /&gt;
Be replaced with this?&lt;br /&gt;
  if(BM_TestHFlag(eve, BM_SELECT))&lt;br /&gt;
&lt;br /&gt;
==== BLI_array_* ====&lt;br /&gt;
BLI_array_* macros are IMHO too convoluted.&lt;br /&gt;
 BLI_array_growone(verts);&lt;br /&gt;
''expands into ...''&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
((void *)(verts)==((void*)0) &amp;amp;&amp;amp; (void *)(_verts_static) != ((void*)0) ? &lt;br /&gt;
((verts=(void*)_verts_static), ++_verts_count) : ((signed int)(((void *)(verts) &lt;br /&gt;
== (void *)_verts_static &amp;amp;&amp;amp;(void *)(verts) != ((void*)0)) ? (sizeof(_verts_static) &lt;br /&gt;
/ sizeof(*verts)) : ((verts)==((void*)0) ? 0 : EM_allocN_len(verts) /&lt;br /&gt;
sizeof(*verts)))) &amp;gt; _verts_count ? ++_verts_count : ((_verts_tmp= &lt;br /&gt;
MEM_callocN(sizeof(*verts)*(_verts_count*2 +2), &amp;quot;verts&amp;quot; &amp;quot; &amp;quot;&lt;br /&gt;
&amp;quot;/data/src/blender/bmesh/source/blender/bmesh/operators/removedoubles.c&amp;quot;&lt;br /&gt;
&amp;quot; &amp;quot;)), (verts &amp;amp;&amp;amp; memcpy(_verts_tmp, verts, sizeof(*verts) * _verts_count)), &lt;br /&gt;
(verts &amp;amp;&amp;amp; ((void *)(verts) != (void*)_verts_static ? (_MEM_freeN(verts, &lt;br /&gt;
&amp;quot;/data/src/blender/bmesh/source/blender/bmesh/operators/removedoubles.c&amp;quot;,&lt;br /&gt;
 462), verts) : verts)), &lt;br /&gt;
(verts = _verts_tmp), _verts_count++)) &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
these can be made into functions.&lt;br /&gt;
&lt;br /&gt;
==== bmesh_class.h struct defintions ====&lt;br /&gt;
&amp;lt;s&amp;gt;bmesh_class.h splits up structs in a way which makes them hard to read &amp;amp; IMHO is too fine grained.&lt;br /&gt;
Being able to open a header and know what the stricture is. is nice, but with this you need to follow each define.&lt;br /&gt;
&lt;br /&gt;
If these defines are useful to keep then a commented, expanded version if the struct would still be useful for devs reading the code, these shouldnt change often so while its a kludge is still an improvement IMHO.&lt;br /&gt;
&lt;br /&gt;
BM_ADJ_* macros are all only used once, so they could be removed and copied into the definitions - surrounded by comments.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define BM_BASE_VHEAD\&lt;br /&gt;
	BMHeader head;\&lt;br /&gt;
	float co[3];\&lt;br /&gt;
	float no[3];&lt;br /&gt;
&lt;br /&gt;
typedef struct BMBaseVert {&lt;br /&gt;
	BM_BASE_VHEAD&lt;br /&gt;
} BMBaseVert;&lt;br /&gt;
&lt;br /&gt;
/* --- snip --- */&lt;br /&gt;
&lt;br /&gt;
#define BM_ADJ_VHEAD(etype)\&lt;br /&gt;
	BM_BASE_VHEAD\&lt;br /&gt;
	struct etype *e;&lt;br /&gt;
&lt;br /&gt;
typedef struct BMVert {&lt;br /&gt;
	BM_ADJ_VHEAD(BMEdge)&lt;br /&gt;
} BMVert;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* I removed all that crap; it was part of a plan to make bmesh more usable for modifiers, but that ended up falling through. [[User:Joeedh|Joeedh]] 21:39, 16 May 2011 (CEST)&lt;br /&gt;
&lt;br /&gt;
== API ==&lt;br /&gt;
&lt;br /&gt;
==== Operator API ====&lt;br /&gt;
BMO - bmeshes internal operator api (not to be confused with blenders operators), has some areas I would like to see changed.&lt;br /&gt;
&lt;br /&gt;
Having a BMO I can see being useful, to handle mesh operators in a consistent way.&lt;br /&gt;
&lt;br /&gt;
But In general it seems to me that BMO's are implemented too high level, (closer to wmOperator's), where this could be avoided since they will be called in C and IMHO there such abstractions can be avoided.&lt;br /&gt;
&lt;br /&gt;
===== Calling =====&lt;br /&gt;
Firstly calling the operators with strings IMHO is not a good design choice since it allows errors to pass silently and doesn't fit well with a C api. unlike printf formatting the compiler cant find errors in it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
BMO_CallOpf(bm, &amp;quot;removedoubles verts=%fv dist=%f&amp;quot;, VERT_MARK, 0.001f);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This could be made into an api call, or, if it must be wrapped by a general operator call it could be done differently.&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
// typical api call &lt;br /&gt;
BMO_call_removedoubles(bm, VERT_MARK, 0.001f);&lt;br /&gt;
&lt;br /&gt;
// if wrapping is needed an intermediate variable can be passed to the caller.&lt;br /&gt;
BMO_CallOp(bm, BMO_removedoubles, VERT_MARK, 0.001f));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Type System =====&lt;br /&gt;
BMO's have their own basic type system, a little like IDProperties.&lt;br /&gt;
&lt;br /&gt;
Rather then having a concept of bmesh-operator-slots, why not just have a struct allocated for each bmo (like modifier settings), it can be memcpy'd and we avoid having to define an api to convert, copy, typecheck arguments.&lt;br /&gt;
&lt;br /&gt;
* That violates the operator design, where slots are meant to be piped to each other. [[User:Joeedh|Joeedh]] 21:39, 16 May 2011 (CEST)&lt;br /&gt;
&lt;br /&gt;
''note, slots are analogous to operator arguments.''&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
BMOpSlot *BMO_GetSlot(struct BMOperator *op, const char *slotname);&lt;br /&gt;
void BMO_CopySlot(struct BMOperator *source_op, struct BMOperator *dest_op, const char *src, const char *dst);&lt;br /&gt;
&lt;br /&gt;
void BMO_Set_Float(struct BMOperator *op, const char *slotname, float f);&lt;br /&gt;
float BMO_Get_Float(BMOperator *op, const char *slotname);&lt;br /&gt;
void BMO_Set_Int(struct BMOperator *op, const char *slotname, int i);&lt;br /&gt;
int BMO_Get_Int(BMOperator *op, const char *slotname);&lt;br /&gt;
&lt;br /&gt;
void BMO_Set_Pnt(struct BMOperator *op, const char *slotname, void *p);&lt;br /&gt;
void *BMO_Get_Pnt(BMOperator *op, const char *slotname);&lt;br /&gt;
void BMO_Set_Vec(struct BMOperator *op, const char *slotname, float *vec);&lt;br /&gt;
void BMO_Get_Vec(BMOperator *op, const char *slotname, float *vec_out);&lt;br /&gt;
&lt;br /&gt;
void BMO_Set_Mat(struct BMOperator *op, const char *slotname, float *mat, int size);&lt;br /&gt;
void BMO_Get_Mat4(struct BMOperator *op, const char *slotname, float mat[4][4]);&lt;br /&gt;
void BMO_Get_Mat3(struct BMOperator *op, const char *slotname, float mat[3][3]);&lt;br /&gt;
&lt;br /&gt;
void BMO_HeaderFlag_To_Slot(struct BMesh *bm, struct BMOperator *op, const char *slotname, int flag, int type);&lt;br /&gt;
&lt;br /&gt;
int BMO_CountSlotBuf(struct BMesh *bm, struct BMOperator *op, const char *slotname);&lt;br /&gt;
int BMO_CountSlotMap(struct BMesh *bm, struct BMOperator *op, const char *slotname);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bugs/General Issues ==&lt;br /&gt;
This excludes the items already marked BMESH_TODO.&lt;br /&gt;
&lt;br /&gt;
==== Memory Usage ====&lt;br /&gt;
A cube subdivided 9 times with BMesh uses 1.6gig of ram.&lt;br /&gt;
the same test in trunk uses 0.93gig.&lt;br /&gt;
&lt;br /&gt;
While higher memory usage is inevitable with adjacency info it looks like struct members have been added for convenience and not always used that often. &lt;br /&gt;
&lt;br /&gt;
The 'BMHeader' struct used for verts, loops, edges, faces is quite heavy.&lt;br /&gt;
* int eid; // can be removed, its not used currently.&lt;br /&gt;
* int sysflag; // only checked in 1 place and not set anywhere.&lt;br /&gt;
* short type; // could be a char &lt;br /&gt;
* short flag; // could be made a char if some unused flags are removed.&lt;br /&gt;
&lt;br /&gt;
The 'BMFlagLayer' has unused member 'int index'&lt;br /&gt;
&lt;br /&gt;
==== Subsurf Slowdown ====&lt;br /&gt;
* Subsurf is slower in the BMesh branch. simple 2 bone animating suzzane, subsurf level 4 is 5.5-FPS in trunk and 1.2-FPS on the bmesh branch. Also tested in editmode where its slower too.&lt;br /&gt;
&lt;br /&gt;
Benchmark comparison of subsurf-4 Suzzane deformed &amp;amp; hidden, playing the animation, only calculating deform. results from sysprof, release-with-debug-info, without openmp&lt;br /&gt;
 trunk 36590&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
[./bin/blender]                                           0.00%  85.96%&lt;br /&gt;
  In file /lib/libc-2.13.so                              10.61%  12.69%&lt;br /&gt;
  calloc                                                  5.94%   5.94%&lt;br /&gt;
  In file /lib/libm-2.13.so                               5.65%   5.65%&lt;br /&gt;
  free                                                    5.33%   5.33%&lt;br /&gt;
  accumulate_vertex_normals                               4.88%   4.88%&lt;br /&gt;
  ccgSubSurf__calcVertNormals.isra.19                     4.50%   4.50%&lt;br /&gt;
  ccgSubSurf__calcSubdivLevel                             4.25%   4.25%&lt;br /&gt;
  MEM_freeN                                               4.12%   4.12%&lt;br /&gt;
  getFaceIndex                                            4.02%   4.02%&lt;br /&gt;
  memset                                                  2.41%   3.96%&lt;br /&gt;
  In file [heap]                                          0.00%   3.60%&lt;br /&gt;
  armature_deform_verts                                   3.13%   3.13%&lt;br /&gt;
  memcpy                                                  1.80%   1.80%&lt;br /&gt;
  malloc                                                  1.76%   1.76%&lt;br /&gt;
  mul_m4_v3                                               1.75%   1.75%&lt;br /&gt;
  make_memhead_header                                     1.67%   1.67%&lt;br /&gt;
  CustomData_interp                                       1.36%   1.36%&lt;br /&gt;
  ccgSubSurf_getFaceUserData                              1.34%   1.34%&lt;br /&gt;
  normal_quad_v3                                          1.15%   1.15%&lt;br /&gt;
  acosf                                                   1.15%   1.15%&lt;br /&gt;
  mesh_calc_normals                                       1.14%   1.14%&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 bmesh 36589&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
[./blender.bin]                                           0.00%  94.60%&lt;br /&gt;
  ccgDM_getFinalVert                                     30.93%  30.93%&lt;br /&gt;
  memset                                                 13.18%  13.20%&lt;br /&gt;
  No map [./blender.bin]                                  0.00%  12.04%&lt;br /&gt;
  cgdm_loopIterStep                                       4.41%   4.41%&lt;br /&gt;
  getCCGDerivedMesh                                       3.37%   3.37%&lt;br /&gt;
  mesh_recalcTesselation                                  2.12%   2.33%&lt;br /&gt;
  In file [heap]                                          0.00%   1.86%&lt;br /&gt;
  In file /lib/libm-2.13.so                               1.67%   1.67%&lt;br /&gt;
  accumulate_vertex_normals                               1.65%   1.65%&lt;br /&gt;
  new_mem_element                                         1.54%   1.54%&lt;br /&gt;
  ccgDM_copyFinalFaceArray                                1.44%   1.44%&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since ccgDM_getFinalVert is identical in both, it seems likely that its being called a lot more though this needs to be further tested.&lt;br /&gt;
&lt;br /&gt;
==== Derived Mesh CDDM Assumed ====&lt;br /&gt;
Derived mesh type CDDM is assumed in various places when it may not be a CDDM derived mesh type.&lt;br /&gt;
* subsurf's cgdm_newFaceIter(), cgdm_getMinMax() only takes CCGDerivedMesh*, but the function argument is DerivedMesh*.&lt;br /&gt;
* arrayModifier_doArray(), asserts 'All modifiers return CDDM' - is this true?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Update r39987 =&lt;br /&gt;
&lt;br /&gt;
After looking over BMesh code some more I've come up with some more suggested changes.&lt;br /&gt;
&lt;br /&gt;
== Reduce BMO String Lookups ==&lt;br /&gt;
&lt;br /&gt;
These functions all use string loop lookups (strcmp in a loop to find the named operator slot) ...&lt;br /&gt;
* BMO_Insert_MapInt&lt;br /&gt;
* BMO_Insert_MapFloat&lt;br /&gt;
* BMO_Insert_MapPointer&lt;br /&gt;
* BMO_Get_MapFloat&lt;br /&gt;
* BMO_Get_MapInt&lt;br /&gt;
* BMO_Get_MapPointer&lt;br /&gt;
&lt;br /&gt;
For passing settings to bmesh operators this is ok, but when its called on mesh data - each vertex/edge/face; I think this is really not efficient, especially when its looking up the same slot every time.&lt;br /&gt;
&lt;br /&gt;
Example from: source/blender/bmesh/operators/removedoubles.c&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
BM_ITER(v, &amp;amp;iter, bm, BM_VERTS_OF_MESH, NULL) {&lt;br /&gt;
  if (BMO_Get_MapPointer(bm, op, &amp;quot;targetmap&amp;quot;, v)) /* string lookup on every vert! */&lt;br /&gt;
    BMO_SetFlag(bm, v, ELE_DEL);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Talked with Brigg's and apparently this used to use fixed slot values rather than string lookups, think going back to something like this would be better, or at very least cache the string lookups so they don't get called in loops.&lt;br /&gt;
&lt;br /&gt;
== Replace BMO &amp;quot;mesh&amp;quot; and &amp;quot;object&amp;quot; pointer use ==&lt;br /&gt;
&lt;br /&gt;
Replace &amp;quot;mesh&amp;quot; and &amp;quot;object&amp;quot; Operator pointers.&lt;br /&gt;
&lt;br /&gt;
 Object *ob = BMO_Get_Pnt(op, &amp;quot;object&amp;quot;);&lt;br /&gt;
 Mesh *me = BMO_Get_Pnt(op, &amp;quot;mesh&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
...with&lt;br /&gt;
&lt;br /&gt;
 Object *ob = bm-&amp;gt;ob;&lt;br /&gt;
 Mesh *me = bm-&amp;gt;ob-&amp;gt;data;&lt;br /&gt;
&lt;br /&gt;
Since these are available from 'bm' I dont see the need to use operator pointers.&lt;br /&gt;
&lt;br /&gt;
== Don't inline BLI_smallhash.h ==&lt;br /&gt;
&lt;br /&gt;
IMHO these functions are too big to inline, BLI_smallhash_insert for example is 45sloc, think these would be better suited to being normal functions.&lt;br /&gt;
&lt;br /&gt;
This won't stop it from using stack memory.&lt;br /&gt;
&lt;br /&gt;
== CDDM In-efficiency ==&lt;br /&gt;
&lt;br /&gt;
Note that these are not high priority compared to crash fixes but think they should be resolved still.&lt;br /&gt;
&lt;br /&gt;
* CDDM_calc_normals tessellates all polygons twice (calling both cdDM_recalcTesselation2 and cdDM_recalcTesselation). &lt;br /&gt;
&lt;br /&gt;
* CDDM_tessfaces_to_faces calls CDDM_calc_edges() every time, IMHO this istoo much defensive programming, were a fairly slow function is called just because it *might* be needed, probably callers should be responsible for ensuring there is correct edge data. (in some cases we know the edges are correct - MOD_screw.c is one case) - or this could be made an argument.&amp;lt;br&amp;gt;Note, perhaps we can skip optimizing this if it will be replaced eventually by code that writes polygons and loops directly.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Update 43694 =&lt;br /&gt;
&lt;br /&gt;
Nearing merge, I was still unsure as to what advantages cellalloc gave, so I tested release builds.&lt;br /&gt;
&lt;br /&gt;
The test case was sintel with heavy use of deform groups.&lt;br /&gt;
* all non mesh objects removed&lt;br /&gt;
* all meshes without vertex groups removed.&lt;br /&gt;
* full copy of the scene 8 times.&lt;br /&gt;
&lt;br /&gt;
* without cellalloc: 721mb&lt;br /&gt;
* with cellalloc: 681mb&lt;br /&gt;
* without cellalloc, with jemalloc:  568mb&lt;br /&gt;
&lt;br /&gt;
Tested on 64bit linux&lt;br /&gt;
&lt;br /&gt;
So to avoid complications from cellmalloc and since we use jemalloc on linux, I'm removing cellalloc from the bmesh branch, the issue of many small allocations can be solved separately.&lt;br /&gt;
&lt;br /&gt;
--[[User:Ideasman42|Ideasman42]] 21:15, 25 January 2012 (CET)&lt;/div&gt;</summary>
		<author><name>wiki&gt;Ideasman42</name></author>
		
	</entry>
</feed>