[Bf-committers] UnlimitedClay in 3,2,1
raulf at info.upr.edu.cu
raulf at info.upr.edu.cu
Wed Apr 27 19:50:50 CEST 2011
Hi all :)
As promised yesterday here is the UnlimitedClay patch against an old
revision (32564), is a heavy patch where I move data a lot among files,
basically due to the need to expose editmesh functionality to the sculpt
module and viceversa, remember that UnlimietdClay is more like a hybrid of
both modes , also there are some incomplete features or temporal solutions
there (like drawing functions).
There are several smoothing algorithm that I have earlier release as a
cleaner patch, and rewritten to to avoid introducing new terms , so they
can be used here just for testing purposes, I don't recomend to integrate
them as they are in this patch, if any dev is interesting in them please
search the Blender patch tracker where the correct patch is floating.
A new rewrite must be done for the new BMesh and also to implement better
PBVH support, I'm preparing a PDF where I explains the basic for dynamic
subdivision sculpting that will ease the task :)
I'm sure all the issues will be overcome soon. Enough of talk ;)
PS: Forgive me for pasting the patch here but PasteAll.org takes ages to
load for me O.o!
//------ UnlimitedClay alpha 2 patch -------------------------------------
Index: release/scripts/ui/properties_data_modifier.py
===================================================================
--- release/scripts/ui/properties_data_modifier.py (revision 32564)
+++ release/scripts/ui/properties_data_modifier.py (working copy)
@@ -568,6 +568,13 @@
def SOFT_BODY(self, layout, ob, md):
layout.label(text="See Soft Body panel.")
+ def UCLAY(self, layout, ob, md):
+ split = layout.split()
+ col = split.column()
+ col.prop(md, "detail")
+ col.prop(md, "smoothness")
+ col.prop(md, "relax")
+
def SOLIDIFY(self, layout, ob, md):
split = layout.split()
Index: source/blender/blenkernel/BKE_cdderivedmesh.h
===================================================================
--- source/blender/blenkernel/BKE_cdderivedmesh.h (revision 32564)
+++ source/blender/blenkernel/BKE_cdderivedmesh.h (working copy)
@@ -50,7 +50,7 @@
calculate normals as those functions will automtically create new
data to not overwrite the original */
struct DerivedMesh *CDDM_from_mesh(struct Mesh *mesh, struct Object *ob);
-
+struct DerivedMesh *CDDM_from_editmesh_select(struct EditMesh *em, struct
Mesh *me);
/* creates a CDDerivedMesh from the given EditMesh */
struct DerivedMesh *CDDM_from_editmesh(struct EditMesh *em, struct Mesh
*me);
@@ -114,3 +114,4 @@
struct MFace *CDDM_get_faces(struct DerivedMesh *dm);
#endif
+
Index: source/blender/blenkernel/BKE_DerivedMesh.h
===================================================================
--- source/blender/blenkernel/BKE_DerivedMesh.h (revision 32564)
+++ source/blender/blenkernel/BKE_DerivedMesh.h (working copy)
@@ -62,6 +62,7 @@
struct GPUDrawObject;
struct ListBase;
struct PBVH;
+struct UClayModifierData;
/* number of sub-elements each mesh element has (for interpolation) */
#define SUB_ELEMS_VERT 0
@@ -122,6 +123,14 @@
struct MEdge *(*getEdgeArray)(DerivedMesh *dm);
struct MFace *(*getFaceArray)(DerivedMesh *dm);
+ /* return a pointer to the entire list of editverts/editedges/editface
from the
+ * derived mesh.
+ */
+ struct EditVert *(*getEditVerts)(DerivedMesh *dm);
+ struct EditEdge *(*getEditEdges)(DerivedMesh *dm);
+ struct EditFace *(*getEditFaces)(DerivedMesh *dm);
+
+
/* copy all verts/edges/faces from the derived mesh into
* *{vert/edge/face}_r (must point to a buffer large enough)
*/
@@ -542,5 +551,24 @@
/* Set object's bounding box based on DerivedMesh min/max data */
void DM_set_object_boundbox(struct Object *ob, DerivedMesh *dm);
+typedef struct EditMeshDerivedMesh{
+ struct DerivedMesh dm;
+
+ struct EditMesh *em;
+ float (*vertexCos)[3];
+ float (*vertexNos)[3];
+ float (*faceNos)[3];
+
+ struct PBVH *pbvh;
+ unsigned int pbvh_draw, modified;
+
+ //struct UClayModifierData *ucmd;
+ struct Scene *scene;
+ struct Object *ob;
+ int numverts, numedges, numfaces;
+} EditMeshDerivedMesh;
+
+DerivedMesh *uclay_dm_create_from_derived(struct UClayModifierData *ucmd,
int local_ucmd, DerivedMesh *dm,struct Object *ob,struct Scene
*scene,float radius, int useRenderParams,int isFinalCalc);
#endif
+
Index: source/blender/blenkernel/BKE_modifier.h
===================================================================
--- source/blender/blenkernel/BKE_modifier.h (revision 32564)
+++ source/blender/blenkernel/BKE_modifier.h (working copy)
@@ -311,6 +311,7 @@
int modifiers_isSoftbodyEnabled(struct Object *ob);
int modifiers_isClothEnabled(struct Object *ob);
int modifiers_isParticleEnabled(struct Object *ob);
+int modifiers_isUClayEnabled(struct Object *ob);
struct Object *modifiers_isDeformedByArmature(struct Object *ob);
struct Object *modifiers_isDeformedByLattice(struct Object *ob);
@@ -340,3 +341,4 @@
#endif
+
Index: source/blender/blenkernel/BKE_multires.h
===================================================================
--- source/blender/blenkernel/BKE_multires.h (revision 32564)
+++ source/blender/blenkernel/BKE_multires.h (working copy)
@@ -39,8 +39,10 @@
struct Object;
void multires_mark_as_modified(struct Object *ob);
+void uclay_mark_as_modified(struct Object *ob); //Mio Eventually moved
void multires_force_update(struct Object *ob);
+void uclay_force_update(struct Object *ob);
void multires_force_render_update(struct Object *ob);
void multires_force_external_reload(struct Object *ob);
@@ -73,3 +75,4 @@
#endif
+
Index: source/blender/blenkernel/BKE_paint.h
===================================================================
--- source/blender/blenkernel/BKE_paint.h (revision 32564)
+++ source/blender/blenkernel/BKE_paint.h (working copy)
@@ -38,8 +38,66 @@
struct Paint;
struct PBVH;
struct Scene;
-struct StrokeCache;
+typedef struct StrokeCache {
+ /* Invariants */
+ float initial_radius;
+ float scale[3];
+ int flag;
+ float clip_tolerance[3];
+ float initial_mouse[2];
+
+ /* Variants */
+ float radius;
+ float radius_squared;
+ //float traced_location[3];
+ float true_location[3];
+ float location[3];
+
+ float pen_flip;
+ float invert;
+ float pressure;
+ float mouse[2];
+ float bstrength;
+ float tex_mouse[2];
+
+ /* The rest is temporary storage that isn't saved as a property */
+
+ int first_time; /* Beginning of stroke may do some things special */
+
+ struct bglMats *mats;
+
+ /* Clean this up! */
+ struct ViewContext *vc;
+ struct Brush *brush;
+
+ float (*face_norms)[3]; /* Copy of the mesh faces' normals */
+ float special_rotation; /* Texture rotation (radians) for anchored and
rake modes */
+ int pixel_radius, previous_pixel_radius;
+ float grab_delta[3], grab_delta_symmetry[3];
+ float old_grab_location[3], orig_grab_location[3];
+
+ int symmetry; /* Symmetry index between 0 and 7 bit combo 0 is Brush only;
+ 1 is X mirror; 2 is Y mirror; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is
XYZ */
+ int mirror_symmetry_pass; /* the symmetry pass we are currently on
between 0 and 7*/
+ float true_view_normal[3];
+ float view_normal[3];
+ float last_area_normal[3];
+ float last_center[3];
+ int radial_symmetry_pass;
+ float symm_rot_mat[4][4];
+ float symm_rot_mat_inv[4][4];
+ float last_rake[2]; /* Last location of updating rake rotation */
+ int original;
+
+ float vertex_rotation;
+
+ char saved_active_brush_name[24];
+ int alt_smooth;
+
+ float plane_trim_squared;
+} StrokeCache;
+
extern const char PAINT_CURSOR_SCULPT[3];
extern const char PAINT_CURSOR_VERTEX_PAINT[3];
extern const char PAINT_CURSOR_WEIGHT_PAINT[3];
@@ -63,8 +121,9 @@
typedef struct SculptSession {
struct ProjVert *projverts;
- /* Mesh data (not copied) can come either directly from a Mesh, or from
a MultiresDM */
+ /* Mesh data (not copied) can come either directly from a Mesh, from a
MultiresDM or EditMeshDM */
struct MultiresModifierData *multires; /* Special handling for multires
meshes */
+ struct UClayModifierData *uclay; /* Special handling for uclay meshes */
struct MVert *mvert;
struct MFace *mface;
int totvert, totface;
Index: source/blender/blenkernel/intern/cdderivedmesh.c
===================================================================
--- source/blender/blenkernel/intern/cdderivedmesh.c (revision 32564)
+++ source/blender/blenkernel/intern/cdderivedmesh.c (working copy)
@@ -222,7 +222,7 @@
BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
me->totface, me->totvert);
}
-
+
return cddm->pbvh;
}
@@ -1617,6 +1617,106 @@
return dm;
}
+DerivedMesh *CDDM_from_editmesh_select(EditMesh *em, Mesh *me)
+{
+ DerivedMesh *dm = CDDM_new(BLI_countlist(&em->verts),
+ BLI_countlist(&em->edges),
+ BLI_countlist(&em->faces));
+ CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
+ EditVert *eve;
+ EditEdge *eed;
+ EditFace *efa;
+ MVert *mvert = cddm->mvert;
+ MEdge *medge = cddm->medge;
+ MFace *mface = cddm->mface;
+ int i, *index;
+
+ dm->deformedOnly = 1;
+
+ CustomData_merge(&em->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
+ CD_CALLOC, dm->numVertData);
+ /* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
+ CD_CALLOC, dm->numEdgeData); */
+ CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
+ CD_CALLOC, dm->numFaceData);
+
+ /* set eve->hash to vert index */
+ for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i)
+ eve->tmp.l = i;
+
+ /* Need to be able to mark loose edges */
+ for(eed = em->edges.first; eed; eed = eed->next) {
+ eed->f2 = 0;
+ }
+ for(efa = em->faces.first; efa; efa = efa->next) {
+ efa->e1->f2 = 1;
+ efa->e2->f2 = 1;
+ efa->e3->f2 = 1;
+ if(efa->e4) efa->e4->f2 = 1;
+ }
+
+ index = dm->getVertDataArray(dm, CD_ORIGINDEX);
+ for(i = 0, eve = em->verts.first; i < dm->numVertData;
+ i++, eve = eve->next, index++) {
+ MVert *mv = &mvert[i];
+
+ VECCOPY(mv->co, eve->co);
+
+ mv->no[0] = eve->no[0] * 32767.0;
+ mv->no[1] = eve->no[1] * 32767.0;
+ mv->no[2] = eve->no[2] * 32767.0;
+ mv->bweight = (unsigned char) (eve->bweight * 255.0f);
+
+ mv->mat_nr = 0;
+ if (eve->f & SELECT) mv->flag |= SELECT;
+ else mv->flag = 0;//Mio
+
+ *index = i;
+
+ CustomData_from_em_block(&em->vdata, &dm->vertData, eve->data, i);
+ }
+
+ index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
+ for(i = 0, eed = em->edges.first; i < dm->numEdgeData;
+ i++, eed = eed->next, index++) {
+ MEdge *med = &medge[i];
+
+ med->v1 = eed->v1->tmp.l;
+ med->v2 = eed->v2->tmp.l;
+ med->crease = (unsigned char) (eed->crease * 255.0f);
+ med->bweight = (unsigned char) (eed->bweight * 255.0f);
+ med->flag = ME_EDGEDRAW|ME_EDGERENDER;
+
+ if(eed->seam) med->flag |= ME_SEAM;
+ if(eed->sharp) med->flag |= ME_SHARP;
+ if(!eed->f2) med->flag |= ME_LOOSEEDGE;
+
+ *index = i;
+
+ /* CustomData_from_em_block(&em->edata, &dm->edgeData, eed->data, i); */
+ }
+
+ index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
+ for(i = 0, efa = em->faces.first; i < dm->numFaceData;
+ i++, efa = efa->next, index++) {
+ MFace *mf = &mface[i];
+
+ mf->v1 = efa->v1->tmp.l;
+ mf->v2 = efa->v2->tmp.l;
+ mf->v3 = efa->v3->tmp.l;
+ mf->v4 = efa->v4 ? efa->v4->tmp.l : 0;
+ mf->mat_nr = efa->mat_nr;
+ mf->flag = efa->flag;
+
+ *index = i;
+
+ CustomData_from_em_block(&em->fdata, &dm->faceData, efa->data, i);
+ test_index_face(mf, &dm->faceData, i, efa->v4?4:3);
+ }
+
+ return dm;
+}
+
DerivedMesh *CDDM_from_curve(Object *ob)
{
return CDDM_from_curve_customDB(ob, &((Curve *)ob->data)->disp);
@@ -1914,3 +2014,4 @@
return ((CDDerivedMesh*)dm)->mface;
}
+
Index: source/blender/blenkernel/intern/DerivedMesh.c
===================================================================
--- source/blender/blenkernel/intern/DerivedMesh.c (revision 32564)
+++ source/blender/blenkernel/intern/DerivedMesh.c (working copy)
@@ -66,6 +66,7 @@
///////////////////////////////////
///////////////////////////////////
+#include
"C:\Blender_Build\blenderSVN\source\blender\editors\include\ED_mesh.h"
//temporal hack, find a better way to reference the resource :P
static MVert *dm_getVertArray(DerivedMesh *dm)
{
@@ -445,15 +446,6 @@
///
-typedef struct {
- DerivedMesh dm;
-
- EditMesh *em;
- float (*vertexCos)[3];
- float (*vertexNos)[3];
- float (*faceNos)[3];
-} EditMeshDerivedMesh;
-
static void emDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void
*userData, int index, float *co, float *no_f, short *no_s), void
*userData)
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
@@ -519,8 +511,9 @@
}
static void emDM_drawEdges(DerivedMesh *dm, int UNUSED(drawLooseEdges),
int UNUSED(drawAllEdges))
{
- emDM_drawMappedEdges(dm, NULL, NULL);
+ emDM_drawMappedEdges(dm, NULL, NULL);
}
+
static void emDM_drawMappedEdgesInterp(DerivedMesh *dm, int
(*setDrawOptions)(void *userData, int index), void
(*setDrawInterpOptions)(void *userData, int index, float t), void
*userData)
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
@@ -1057,7 +1050,7 @@
EditVert *eve;
int i;
- if (emdm->em->verts.first) {
+ if (emdm->em->verts.first) {
for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) {
if (emdm->vertexCos) {
DO_MINMAX(emdm->vertexCos[i], min_r, max_r);
@@ -1067,27 +1060,27 @@
}
} else {
min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
- }
+ }
}
static int emDM_getNumVerts(DerivedMesh *dm)
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- return BLI_countlist(&emdm->em->verts);
+ return emdm->numverts; //BLI_countlist(&emdm->em->verts);
}
static int emDM_getNumEdges(DerivedMesh *dm)
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- return BLI_countlist(&emdm->em->edges);
+ return emdm->numedges; //BLI_countlist(&emdm->em->edges);
}
static int emDM_getNumFaces(DerivedMesh *dm)
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- return BLI_countlist(&emdm->em->faces);
+ return emdm->numfaces; //BLI_countlist(&emdm->em->faces);
}
static void emDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
@@ -1220,19 +1213,20 @@
vert_r->mat_nr = 0;
vert_r->flag = 0;
vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
+
+ /* store vertex indices in tmp union */
+ ev->tmp.l = (intptr_t) i; //Mio
}
}
-static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
+static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
{
EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
EditEdge *ee = em->edges.first;
- EditVert *ev;
- int i;
-
+
/* store vertex indices in tmp union */
- for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
- ev->tmp.l = (intptr_t) i;
+ //for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
+ // ev->tmp.l = (intptr_t) i;
for( ; ee; ee = ee->next, ++edge_r) {
edge_r->crease = (unsigned char) (ee->crease*255.0f);
@@ -1255,12 +1249,10 @@
{
EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
EditFace *ef = em->faces.first;
- EditVert *ev;
- int i;
-
+
/* store vertexes indices in tmp union */
- for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
- ev->tmp.l = (intptr_t) i;
+ //for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
+ // ev->tmp.l = (intptr_t) i;
for( ; ef; ef = ef->next, ++face_r) {
face_r->mat_nr = ef->mat_nr;
@@ -1316,24 +1308,377 @@
static void emDM_release(DerivedMesh *dm)
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-
- if (DM_release(dm)) {
+
+ if (DM_release(dm)) { //check the fact that emDM release is called a lot
and multires no, have to do with multires needs free
+ if (emdm->modified){ //if is in sculpt mode
+ //ccgdm->multires.update(dm);
+ //load_editMesh(emdm->scene, emdm->ob); //apply editmesh to mesh
+ //not needed?
+ //BLI_pbvh_free(emdm->pbvh);
+ //MEM_freeN(emdm->pbvh);
+ //emdm->pbvh = NULL;
+ }
+
if (emdm->vertexCos) {
MEM_freeN(emdm->vertexCos);
MEM_freeN(emdm->vertexNos);
- MEM_freeN(emdm->faceNos);
- }
+ MEM_freeN(emdm->faceNos);
+ }
MEM_freeN(emdm);
}
}
+//----
+static int em_can_pbvh_draw(Object *ob, DerivedMesh *dm)
+{
+ EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *) dm;
+ Mesh *me= (ob)? ob->data: NULL;
+
+ if(ob->sculpt->modifiers_active) return 0;
+
+ return 1; //?(emdm->em->allverts == me->mvert) || ob->sculpt->kb;
+}
+
+
+static int can_pbvh_draw_uclay(Object *ob, DerivedMesh *dm)
+{
+ EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh*) dm;
+ Mesh *me= (ob)? ob->data: NULL;
+ EditMesh *em;
+ em = (EditMesh *)me->edit_mesh;
+
+ if(ob->sculpt->modifiers_active) return 0;
+
+ return 1; //(emdm->em == em) || ob->sculpt->kb;
+}
+
+static struct PBVH *emDM_getPBVH(Object *ob, DerivedMesh *dm) //check why
this is called several times more than other methods, performance eater
+{
+ EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *) dm;
+ EditFace *efa = NULL;
+ EditMesh *em;
+ Mesh *me;
+ int i = 0, totface = 0, totvert= 0;
+
+ if(!ob) {
+ emdm->pbvh= NULL;
+ return NULL;
+ }
+
+ if(!ob->sculpt)
+ return NULL;
+
+ if(ob->sculpt->pbvh) {
+ emdm->pbvh= ob->sculpt->pbvh;
+ emdm->pbvh_draw = can_pbvh_draw_uclay(ob, dm);
+ }
+
+ me= (ob)? ob->data: NULL;
+ em = ((struct EditMesh *)emdm->em);
+
+ if (em->faces.first) totface = emdm->numfaces;
+ if (em->verts.first) totvert = emdm->numverts;
+
+ //if(emdm->pbvh){ //handle here topology changes, updates
+ // BLI_pbvh_update_editmesh(emdm->pbvh, em->faces.first,
em->verts.first, totface, totvert);
+
+ // emdm->pbvh_draw = can_pbvh_draw_uclay(ob, dm);
+ //} else {
+ /* no pbvh exists yet, we need to create one. only in case of unlimited
clay
+ we build a pbvh over the modified mesh, in other cases the base mesh
+ is being sculpted, so we build a pbvh from that. */
+ emdm->pbvh = BLI_pbvh_new();
+ BLI_pbvh_build_editmesh(emdm->pbvh, em->faces.first, em->verts.first,
totface, totvert);
+ emdm->pbvh_draw = can_pbvh_draw_uclay(ob, dm);
+ //}
+ return emdm->pbvh;
+}
+
+static void emDM_drawVerts(DerivedMesh *dm) //implementarla mejor despues
+{
+ EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *) dm;
+ EditVert *eve;
+
+ if( GPU_buffer_legacy(dm) ) {
+ glBegin(GL_POINTS);
+ for(eve= emdm->em->verts.first; eve; eve= eve->next)
+ glVertex3fv(eve->co);
+ glEnd();
+ }
+ else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster
rendering */
+ GPU_vertex_setup(dm);
+ if( !GPU_buffer_legacy(dm) ) {
+ if(dm->drawObject->nelements) glDrawArrays(GL_POINTS,0,
dm->drawObject->nelements);
+ else glDrawArrays(GL_POINTS,0, dm->drawObject->nlooseverts);
+ }
+ GPU_buffer_unbind();
+ }
+}
+
+static void emDM_drawLooseEdges(DerivedMesh *dm)
+{
+ EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *) dm;
+ EditEdge *eed;
+ int i;
+ i=0;
+ if( GPU_buffer_legacy(dm) ) {
+ DEBUG_VBO( "Using legacy code. emDM_drawLooseEdges\n" );
+ glBegin(GL_LINES);
+ for(eed= emdm->em->edges.first; eed; eed= eed->next) {
+ if(eed->f&ME_LOOSEEDGE) { //?
+ glVertex3fv(eed->v1->co);
+ glVertex3fv(eed->v2->co);
+ }
+ }
+ glEnd();
+ }
+ else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster
rendering */
+ int prevstart = 0;
+ int prevdraw = 1;
+ int draw = 1;
+
+ GPU_edge_setup(dm);
+ if( !GPU_buffer_legacy(dm) ) {
+ for(eed= emdm->em->edges.first; eed; eed= eed->next) {
+ if(eed->f&ME_LOOSEEDGE) {
+ draw = 1;
+ }
+ else {
+ draw = 0;
+ }
+ if( prevdraw != draw ) {
+ if( prevdraw > 0 && (i-prevstart) > 0) {
+ GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES,
prevstart*2, (i-prevstart)*2 );
+ }
+ prevstart = i;
+ }
+ prevdraw = draw;
+ }
+ if( prevdraw > 0 && (i-prevstart) > 0 ) {
+ GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES,
prevstart*2, (i-prevstart)*2 );
+ }
+ }
+ GPU_buffer_unbind();
+ }
+}
+
+static void emDM_drawFacesSolid(DerivedMesh *dm, float
(*partial_redraw_planes)[4], int fast, int (*setMaterial)(int, void
*attribs)) {
+ EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *) dm;
+ EditVert *eve = emdm->em->verts.first;
+ EditFace *efa = emdm->em->faces.first;
+ float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
+ int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
+
+ if(emdm->pbvh && emdm->pbvh_draw) {
+ if(dm->numFaceData) {
+ float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
+
+ glShadeModel((efa->flag & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
+ BLI_pbvh_draw(emdm->pbvh, partial_redraw_planes, face_nors, (efa->flag
& ME_SMOOTH)); //implement this?¿
+ glShadeModel(GL_FLAT);
+ }
+ return;
+ }
+
+ if( GPU_buffer_legacy(dm) ) {
+ DEBUG_VBO( "Using legacy code. cdDM_drawFacesSolid\n" );
+ glBegin(glmode = GL_QUADS);
+ for(efa= emdm->em->faces.first; efa; efa= efa->next) {
+ int new_glmode, new_matnr, new_shademodel;
+
+ new_glmode = efa->v4?GL_QUADS:GL_TRIANGLES;
+ new_matnr = 1; //mface->mat_nr + 1;
+ new_shademodel = (efa->flag & ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
+
+ if(new_glmode != glmode || new_matnr != matnr
+ || new_shademodel != shademodel) {
+ glEnd();
+
+ drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
+
+ glShadeModel(shademodel = new_shademodel);
+ glBegin(glmode = new_glmode);
+ }
+
+ if(drawCurrentMat) {
+ if(shademodel == GL_FLAT) {
+ if (nors) {
+ glNormal3fv(nors);
+ }
+ else {
+ /* TODO make this better (cache facenormals as layer?) */
+ float nor[3];
+ if(efa->v4) {
+ normal_quad_v3( nor, efa->v1->co, efa->v2->co, efa->v3->co,
efa->v4->co);
+ } else {
+ normal_tri_v3( nor,efa->v1->co, efa->v2->co, efa->v3->co);
+ }
+ glNormal3fv(nor);
+ }
+ }
+ glNormal3fv(efa->v1->no);
+ glVertex3fv(efa->v1->co);
+
+ glNormal3fv(efa->v2->no);
+ glVertex3fv(efa->v2->co);
+
+ glNormal3fv(efa->v3->no);
+ glVertex3fv(efa->v3->co);
+
+ if(efa->v4) {
+ glNormal3fv(efa->v4->no);
+ glVertex3fv(efa->v4->co);
+ }
+ }
+
+ if(nors) nors += 3;
+ }
+ glEnd();
+ }
+ else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster
rendering */
+ GPU_vertex_setup( dm );
+ GPU_normal_setup( dm );
+ if( !GPU_buffer_legacy(dm) ) {
+ glShadeModel(GL_SMOOTH);
+ for( a = 0; a < dm->drawObject->nmaterials; a++ ) {
+ if( setMaterial(dm->drawObject->materials[a].mat_nr+1, NULL) )
+ glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
dm->drawObject->materials[a].end-dm->drawObject->materials[a].start);
+ }
+ }
+ GPU_buffer_unbind( );
+ }
+
+#undef PASSVERT
+ glShadeModel(GL_FLAT);
+}
+
+static DerivedMesh *getEditMeshDerivedMesh_uclay(EditMesh *em, Object
*ob, float (*vertexCos)[3])
+{
+ EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh
*)MEM_callocN(sizeof(EditMeshDerivedMesh), "emdm");
+ emdm->numverts = BLI_countlist(&em->verts);
+ emdm->numedges = BLI_countlist(&em->edges);
+ emdm->numfaces = BLI_countlist(&em->faces);
+
+ DM_init(&emdm->dm, DM_TYPE_EDITMESH, emdm->numverts , emdm->numedges,
emdm->numfaces);
+ /*/---
+ ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
+ ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
+
+ ccgdm->dm.getFaceMap = ccgDM_getFaceMap;
+ ccgdm->dm.getVertCos = ccgdm_getVertCos;
+ ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
+ //---*/
+
+ emdm->dm.drawFacesSolid = emDM_drawFacesSolid;
+ emdm->dm.drawVerts = emDM_drawVerts; //mio
+ emdm->dm.getPBVH = emDM_getPBVH; //mio
+ emdm->dm.drawLooseEdges = emDM_drawLooseEdges; //mio, needed?
+
+ emdm->dm.getMinMax = emDM_getMinMax;
+
+ emdm->dm.getNumVerts = emDM_getNumVerts; //ok
+ emdm->dm.getNumEdges = emDM_getNumEdges; //ok
+ emdm->dm.getNumFaces = emDM_getNumFaces; //ok
+
+ //emdm->dm.getVertCos = emDM_getVertCos;
+
+ //emdm->dm.getVert = emDM_getVert;
+ //emdm->dm.getEdge = emDM_getEdge;
+ //emdm->dm.getFace = emDM_getFace;
+ emdm->dm.copyVertArray = emDM_copyVertArray; //needed
+ emdm->dm.copyEdgeArray = emDM_copyEdgeArray;
+ emdm->dm.copyFaceArray = emDM_copyFaceArray;
+
+ //emdm->dm.getFaceDataArray = emDM_getFaceDataArray;
+
+ //emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
+ //emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
+ //emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
+
+ emdm->dm.drawEdges = emDM_drawEdges;
+ emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
+ emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
+ emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
+ emdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
+ emdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
+ emdm->dm.drawFacesTex = emDM_drawFacesTex;
+ emdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
+ emdm->dm.drawUVEdges = emDM_drawUVEdges;
+
+ emdm->dm.release = emDM_release;
+
+// emdm->dm.getEditEdges = emDM_getEditEdges;
+// emdm->dm.getEditVerts = emDM_getEditVerts;
+// emdm->dm.getEditFaces = emDM_getEditFaces;
+
+ emdm->em = em;
+// emdm->vertexCos = vertexCos;
+
+ if(CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
+ EditVert *eve;
+ int i;
+
+ DM_add_vert_layer(&emdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
+
+ for(eve = em->verts.first, i = 0; eve; eve = eve->next, ++i)
+ DM_set_vert_data(&emdm->dm, i, CD_MDEFORMVERT,
+ CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT));
+ }
+
+ if(vertexCos) {
+ EditVert *eve;
+ EditFace *efa;
+ int totface = BLI_countlist(&em->faces);
+ int i;
+
+ for (i=0,eve=em->verts.first; eve; eve= eve->next)
+ eve->tmp.l = (intptr_t) i++;
+
+ emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
+ emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
+
+ for(i=0, efa= em->faces.first; efa; i++, efa=efa->next) {
+ float *v1 = vertexCos[(int) efa->v1->tmp.l];
+ float *v2 = vertexCos[(int) efa->v2->tmp.l];
+ float *v3 = vertexCos[(int) efa->v3->tmp.l];
+ float *no = emdm->faceNos[i];
+
+ if(efa->v4) {
+ float *v4 = vertexCos[(int) efa->v4->tmp.l];
+
+ normal_quad_v3( no,v1, v2, v3, v4);
+ add_v3_v3(emdm->vertexNos[(int) efa->v4->tmp.l], no);
+ }
+ else {
+ normal_tri_v3( no,v1, v2, v3);
+ }
+ add_v3_v3(emdm->vertexNos[(int) efa->v1->tmp.l], no);
+ add_v3_v3(emdm->vertexNos[(int) efa->v2->tmp.l], no);
+ add_v3_v3(emdm->vertexNos[(int) efa->v3->tmp.l], no);
+ }
+
+ for(i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
+ float *no = emdm->vertexNos[i];
+ /* following Mesh convention; we use vertex coordinate itself
+ * for normal in this case */
+ if (normalize_v3(no)==0.0) {
+ normalize_v3_v3(no, vertexCos[i]);
+ }
+ }
+ }
+ return (DerivedMesh*) emdm;
+}
+
static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, float
(*vertexCos)[3])
{
- EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
+ EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh
*)MEM_callocN(sizeof(EditMeshDerivedMesh), "emdm"); //?
+ emdm->numverts = BLI_countlist(&em->verts);
+ emdm->numedges = BLI_countlist(&em->edges);
+ emdm->numfaces = BLI_countlist(&em->faces);
- DM_init(&emdm->dm, DM_TYPE_EDITMESH, BLI_countlist(&em->verts),
- BLI_countlist(&em->edges), BLI_countlist(&em->faces));
+ DM_init(&emdm->dm, DM_TYPE_EDITMESH, emdm->numverts,
+ emdm->numedges, emdm->numfaces);
emdm->dm.getMinMax = emDM_getMinMax;
@@ -1416,16 +1761,17 @@
for(i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
float *no = emdm->vertexNos[i];
- /* following Mesh convention; we use vertex coordinate itself
+ /* following Mesh convention; we use vertex coordinate itself
* for normal in this case */
if (normalize_v3(no)==0.0) {
- normalize_v3_v3(no, vertexCos[i]);
+ VECCOPY(no, vertexCos[i]);
+ normalize_v3(no);
}
}
}
return (DerivedMesh*) emdm;
-}
+}
/***/
@@ -2729,7 +3075,550 @@
dm->getMinMax(dm, min, max);
if(!ob->bb)
- ob->bb= MEM_callocN(sizeof(BoundBox), "bb");
+ ob->bb= (BoundBox *)MEM_callocN(sizeof(BoundBox), "bb");
boundbox_set_from_min_max(ob->bb, min, max);
}
+
+
+//------------------------------------------
+void set_border_flag(struct EditMesh *em){
+ EditFace *efa;
+ EditEdge *eed;
+
+ /* clear flag */
+ for (efa=em->faces.first;efa;efa=efa->next){
+ efa->e1->f2 = 0;
+ efa->e2->f2 = 0;
+ efa->e3->f2 = 0;
+ if (efa->e4) efa->e4->f2 = 0;
+ }
+ /* find frontier edges, not shared by other faces */
+ for (efa=em->faces.first;efa;efa=efa->next){
+ efa->e1->f2++;
+ efa->e2->f2++;
+ efa->e3->f2++;
+ if (efa->e4) efa->e4->f2++;
+ }
+
+ /* clear flag verts */
+ for (eed = em->edges.first; eed; eed = eed->next){
+ eed->v1->f2 = 0;
+ eed->v2->f2 = 0;
+ }
+ /* propagate fromtier selection to verts */
+ for (eed = em->edges.first; eed; eed = eed->next){
+ if (eed->f2 == 1){ //is frontier
+ eed->v1->f2 = 1;
+ eed->v2->f2 = 1;
+ }
+ }
+}
+
+void tensate(struct EditMesh *em, float spring_k, float dampfac, float
dtime, float detail){
+ EditFace *efa;
+ float diff[3], dist1, dist2, dist3, dist4, dist5, dist6,
D1,D2,D3,D4,D5,D6, L= 0.f;
+ float k = dtime * spring_k;
+ float end[3]={0.f,0.f,0.f};
+ float delta[3]={0.f,0.f,0.f};
+ float v1[3], v2[3], v3[3], v4[3];
+ float prev_co1[3], prev_co2[3], prev_co3[3], prev_co4[3];
+ int i=0;
+
+ set_border_flag(em);
+
+ for (efa=em->faces.first;efa;efa=efa->next){
+ int fourth_vert_selected = 0;
+ if (efa->v4)
+ if (efa->v4->f & SELECT) fourth_vert_selected = 1;
+
+ //if ((efa->v1->f & SELECT) | (efa->v2->f & SELECT) | (efa->v3->f &
SELECT) | fourth_vert_selected){ //if selected
+ //sub_v3_v3v3(diff, efa->v1->co, efa->v2->co);
+ //dist1 = len_v3(diff);
+
+ //sub_v3_v3v3(diff, efa->v2->co, efa->v3->co);
+ //dist2 = len_v3(diff);
+
+ //sub_v3_v3v3(diff, efa->v3->co, efa->v1->co);
+ //dist3 = len_v3(diff);
+
+ L= 0.f; //0.3333f * (dist1+dist2+dist3);
+
+ for (i=0; i<10; i++){ //first only tris
+ zero_v3(v1); zero_v3(v2); zero_v3(v3), zero_v3(v4);
+
+ copy_v3_v3(prev_co1,efa->v1->co);
+ copy_v3_v3(prev_co2,efa->v2->co);
+ copy_v3_v3(prev_co3,efa->v3->co);
+ if (efa->v4) copy_v3_v3(prev_co4,efa->v4->co);
+
+ //find distance among verts 1-2-3
+ sub_v3_v3v3(diff, prev_co1, prev_co2);
+ dist1 = len_v3(diff);
+
+ sub_v3_v3v3(diff, prev_co2, prev_co3);
+ dist2 = len_v3(diff);
+
+ sub_v3_v3v3(diff, prev_co3, prev_co1);
+ dist3 = len_v3(diff);
+
+ if (efa->v4){
+ sub_v3_v3v3(diff, prev_co1, prev_co4);
+ dist4 = len_v3(diff);
+
+ sub_v3_v3v3(diff, prev_co2, prev_co4);
+ dist5 = len_v3(diff);
+
+ sub_v3_v3v3(diff, prev_co3, prev_co4);
+ dist6 = len_v3(diff);
+
+ D4 = k * (L - dist4);
+ D5 = k * (L - dist5);
+ D6 = k * (L - dist6);
+ }
+
+ D1 = k * (L - dist1);
+ D2 = k * (L - dist2);
+ D3 = k * (L - dist3);
+
+ //v1
+ if (!efa->v1->f2 ){ //&& (efa->v1->f & SELECT)
+ sub_v3_v3v3(end, prev_co2, prev_co1);
+ normalize_v3(end);
+ madd_v3_v3fl(v1, end, -D1);
+
+ sub_v3_v3v3(end, prev_co3, prev_co1);
+ normalize_v3(end);
+ madd_v3_v3fl(v1, end, -D3);
+
+ if (efa->v4){
+ sub_v3_v3v3(end, prev_co4, prev_co1);
+ normalize_v3(end);
+ madd_v3_v3fl(v1, end, -D4);
+ }
+
+ madd_v3_v3fl(v1,v1,-dampfac);
+ madd_v3_v3v3fl(efa->v1->co, prev_co1, v1, dtime);
+
+ //remove movement along vertex normal
+ sub_v3_v3v3(delta, efa->v1->co,prev_co1);
+ project_v3_v3v3(delta, delta, efa->v1->no);
+ sub_v3_v3v3(efa->v1->co,efa->v1->co,delta);
+ }
+ //v2
+ if (!efa->v2->f2 ){ //&& (efa->v2->f & SELECT)
+ sub_v3_v3v3(end, prev_co1, prev_co2);
+ normalize_v3(end);
+ madd_v3_v3fl(v2, end, -D1);
+
+ sub_v3_v3v3(end, prev_co3, prev_co2);
+ normalize_v3(end);
+ madd_v3_v3fl(v2, end, -D2);
+
+ if (efa->v4){
+ sub_v3_v3v3(end, prev_co4, prev_co2);
+ normalize_v3(end);
+ madd_v3_v3fl(v2, end, -D5);
+ }
+
+ madd_v3_v3fl(v2,v2,-dampfac);
+ madd_v3_v3v3fl(efa->v2->co, prev_co2, v2, dtime);
+
+ //remove movement along vertex normal
+ sub_v3_v3v3(delta, efa->v2->co,prev_co2);
+ project_v3_v3v3(delta, delta, efa->v2->no);
+ sub_v3_v3v3(efa->v2->co,efa->v2->co,delta);
+ }
+ //v3
+ if (!efa->v3->f2 ){ //&& (efa->v3->f & SELECT)
+ sub_v3_v3v3(end, prev_co2, prev_co3);
+ normalize_v3(end);
+ madd_v3_v3fl(v3, end, -D2);
+
+ sub_v3_v3v3(end, prev_co1, prev_co3);
+ normalize_v3(end);
+ madd_v3_v3fl(v3, end, -D3);
+
+ if (efa->v4){
+ sub_v3_v3v3(end, prev_co4, prev_co3);
+ normalize_v3(end);
+ madd_v3_v3fl(v3, end, -D6);
+ }
+
+ madd_v3_v3fl(v3,v3,-dampfac);
+ madd_v3_v3v3fl(efa->v3->co, prev_co3, v3, dtime);
+
+ //remove movement along vertex normal
+ sub_v3_v3v3(delta, efa->v3->co,prev_co3);
+ project_v3_v3v3(delta, delta, efa->v3->no);
+ sub_v3_v3v3(efa->v3->co,efa->v3->co,delta);
+ }
+ //v4
+ if (efa->v4){
+ if (!efa->v4->f2 ){ //&& (efa->v4->f & SELECT)
+ sub_v3_v3v3(end, prev_co1, prev_co4);
+ normalize_v3(end);
+ madd_v3_v3fl(v4, end, -D4);
+
+ sub_v3_v3v3(end, prev_co2, prev_co4);
+ normalize_v3(end);
+ madd_v3_v3fl(v4, end, -D5);
+
+ sub_v3_v3v3(end, prev_co3, prev_co4);
+ normalize_v3(end);
+ madd_v3_v3fl(v4, end, -D6);
+
+ madd_v3_v3fl(v4,v4,-dampfac);
+ madd_v3_v3v3fl(efa->v4->co, prev_co4, v4, dtime);
+
+ //remove movement along vertex normal
+ sub_v3_v3v3(delta, efa->v4->co,prev_co4);
+ project_v3_v3v3(delta, delta, efa->v4->no);
+ sub_v3_v3v3(efa->v4->co,efa->v4->co,delta);
+ }
+ }
+ //-----------*/
+ }
+ //}
+ }
+}
+
+void laplacian_relaxation(struct EditMesh *em, float spring_k, float
dampfac, float dtime, float detail){
+ EditEdge *eed;
+ EditVert *eve;
+ float k = dtime * spring_k;
+ float end[3]={0.f,0.f,0.f};
+ float delta[3]={0.f,0.f,0.f};
+ float prev_co[3];
+ int i=0;
+
+ for (i = 0; i<3 ; i++){
+ //set_border_flag(em); //Optional, user defined
+
+ /* clear editvert old_co*/
+ for (eve = em->verts.first; eve; eve = eve->next){
+ zero_v3(eve->old_co);
+ eve->v = 0.f;
+ eve->count = 0;
+ }
+
+ for (eed=em->edges.first;eed;eed=eed->next){
+ if ((!eed->v1->f2 && (eed->v1->f1 == 1)) || (!eed->v2->f2 &&
(eed->v2->f1 == 1)) ){
+ madd_v3_v3fl(eed->v1->old_co, eed->v2->co, 1.f);
+ madd_v3_v3fl(eed->v2->old_co, eed->v1->co, 1.f);
+
+ eed->v1->count += 1.f;
+ eed->v2->count += 1.f;
+ }
+ }
+
+
+ for (eve = em->verts.first; eve; eve = eve->next){
+ if (!eve->f2 && (eve->f1 == SELECT) ){//
+ copy_v3_v3(prev_co,eve->co);
+ mul_v3_fl(eve->old_co, 1.f/eve->count);
+ copy_v3_v3(eve->co, eve->old_co);
+
+ //remove movement along vertex normal
+ sub_v3_v3v3(delta, eve->co,prev_co);
+ project_v3_v3v3(delta, delta, eve->no);
+ sub_v3_v3v3(eve->co,eve->co,delta);
+ }
+ } //*/
+
+ }//for i
+}
+
+void revised_ideal_length_relaxation(struct EditMesh *em, float spring_k,
float dampfac, float dtime, float detail){
+ EditEdge *eed;
+ EditVert *eve;
+ float diff[3], dist1, L= 0.f;
+ float k = dtime * spring_k;
+ float end[3]={0.f,0.f,0.f};
+ float delta[3]={0.f,0.f,0.f};
+
+ int i=0;
+
+ set_border_flag(em);
+
+ /* clear editvert old_co*/
+ for (i = 0; i<1 ; i++){
+ for (eve = em->verts.first; eve; eve = eve->next){
+ zero_v3(eve->sum_co); zero_v3(eve->old_co);
+ eve->v = 0.f;
+ eve->count = 0;
+ eve->w = 0;
+ eve->sum_dist = 0.f;
+ }
+
+ for (eed=em->edges.first;eed;eed=eed->next){
+ sub_v3_v3v3(diff, eed->v1->co, eed->v2->co);
+ dist1 = len_v3(diff);
+
+ eed->v1->sum_dist +=dist1; //accumulate dist from verts
+ eed->v2->sum_dist +=dist1;
+
+ eed->v1->count += 1.f; //count verts
+ eed->v2->count += 1.f;
+ }
+
+ for (eve = em->verts.first; eve; eve = eve->next){
+ eve->sum_dist = eve->sum_dist/eve->count;
+ }
+
+ for (eed=em->edges.first;eed;eed=eed->next){
+ float a = 0.f;
+
+ sub_v3_v3v3(diff, eed->v1->co, eed->v2->co);
+ dist1 = len_v3(diff);
+
+ a = 2.f * dist1/(eed->v1->sum_dist + eed->v2->sum_dist);
+
+ eed->v1->w += a/eed->v1->count;
+ eed->v2->w += a/eed->v2->count;
+ }
+
+ for (eed=em->edges.first;eed;eed=eed->next){
+ sub_v3_v3v3(diff, eed->v1->co, eed->v2->co);
+ dist1 = len_v3(diff);
+
+ eed->v1->sum_co[0] += (dist1 - (eed->v1->sum_dist + eed->v2->sum_dist)
* 0.5f * eed->v1->w) * (eed->v2->co[0] - eed->v1->co[0])/dist1;
+ eed->v1->sum_co[1] += (dist1 - (eed->v1->sum_dist + eed->v2->sum_dist)
* 0.5f * eed->v1->w) * (eed->v2->co[1] - eed->v1->co[1])/dist1;
+ eed->v1->sum_co[2] += (dist1 - (eed->v1->sum_dist + eed->v2->sum_dist)
* 0.5f * eed->v1->w) * (eed->v2->co[2] - eed->v1->co[2])/dist1;
+
+ eed->v2->sum_co[0] += (dist1 - (eed->v1->sum_dist + eed->v2->sum_dist)
* 0.5f * eed->v2->w) * (eed->v1->co[0] - eed->v2->co[0])/dist1;
+ eed->v2->sum_co[1] += (dist1 - (eed->v1->sum_dist + eed->v2->sum_dist)
* 0.5f * eed->v2->w) * (eed->v1->co[1] - eed->v2->co[1])/dist1;
+ eed->v2->sum_co[2] += (dist1 - (eed->v1->sum_dist + eed->v2->sum_dist)
* 0.5f * eed->v2->w) * (eed->v1->co[2] - eed->v2->co[2])/dist1;
+
+ madd_v3_v3fl(eed->v1->old_co, eed->v2->co, 1.f);
+ madd_v3_v3fl(eed->v2->old_co, eed->v1->co, 1.f);
+ }
+
+ for (eve = em->verts.first; eve; eve = eve->next){
+ if (!eve->f2){
+ eve->co[0] = (eve->old_co[0] - eve->sum_co[0])/eve->count;
+ eve->co[1] = (eve->old_co[1] - eve->sum_co[1])/eve->count;
+ eve->co[2] = (eve->old_co[2] - eve->sum_co[2])/eve->count;
+ }
+ }
+
+
+ }//for i
+}
+//----------------------
+void HC_relaxation(struct EditMesh *em, float spring_k, float dampfac,
float dtime, float detail){
+ EditEdge *eed;
+ EditVert *eve;
+ float k = dtime * spring_k;
+ float end[3]={0.f,0.f,0.f};
+ float delta[3]={0.f,0.f,0.f};
+ float diff[3];
+ int i=0;
+ float a = 0.1f;
+ float b = 0.6f;
+
+ set_border_flag(em);
+
+ /* clear editvert old_co*/
+ for (eve = em->verts.first; eve; eve = eve->next){
+ copy_v3_v3(eve->old_co, eve->co);
+ eve->v = 0.f;
+ eve->count = 0;
+ zero_v3(eve->p); zero_v3(eve->b);
+ zero_v3(eve->sum_co); zero_v3(eve->sum_b);
+ }
+
+ /* counting neighbors */
+ for (eed = em->edges.first; eed; eed = eed->next){
+ eed->v1->count++;
+ eed->v2->count++;
+ }
+
+ for (i = 0; i< 4 ; i++){
+ for (eve = em->verts.first; eve; eve = eve->next){
+ zero_v3(eve->sum_co);
+ zero_v3(eve->sum_b);
+ zero_v3(eve->p); zero_v3(eve->b);
+ }
+
+ for (eed = em->edges.first; eed; eed = eed->next){
+ add_v3_v3(eed->v1->sum_co, eed->v2->co);
+ add_v3_v3(eed->v2->sum_co, eed->v1->co);
+ }
+
+ //1rst pass
+ for (eve = em->verts.first; eve; eve = eve->next){
+ copy_v3_v3(diff,eve->sum_co);
+ mul_v3_fl(diff,1.f/eve->count); //diff new position
+
+ copy_v3_v3(eve->p,diff);
+
+ eve->b[0] = diff[0] - (a*eve->old_co[0] + (1.f-a)*eve->co[0]);
+ eve->b[1] = diff[1] - (a*eve->old_co[1] + (1.f-a)*eve->co[1]);
+ eve->b[2] = diff[2] - (a*eve->old_co[2] + (1.f-a)*eve->co[2]);
+ }
+
+ for (eed = em->edges.first; eed; eed = eed->next){
+ add_v3_v3(eed->v1->sum_b, eed->v2->b);
+ add_v3_v3(eed->v2->sum_b, eed->v1->b);
+ }
+ //2nd pass
+ for (eve = em->verts.first; eve; eve = eve->next){
+ if (!eve->f2){ // && (eve->f & SELECT)
+ eve->co[0] = eve->p[0] - (b*eve->b[0] + (1-b)*eve->sum_b[0]/eve->count);
+ eve->co[1] = eve->p[1] - (b*eve->b[1] + (1-b)*eve->sum_b[1]/eve->count);
+ eve->co[2] = eve->p[2] - (b*eve->b[2] + (1-b)*eve->sum_b[2]/eve->count);
+ }
+ }
+
+ }//for i
+}
+//----------------------
+void select_edges_uclay(struct EditMesh *em, float radius, float detail,
int repeat, int edge_treshold){//edge_treshold: fator to trigger edge
splitting
+ EditFace *efa;
+ float diff[3];
+ int i = 0;
+ float dist1, dist2, dist3, s, d;
+
+ for(efa= em->faces.first; efa; efa= efa->next){
+ if (efa->f & SELECT)
+ {
+ float bigger = 0.f;
+ sub_v3_v3v3(diff, efa->e1->v1->co, efa->e1->v2->co);
+ dist1 = len_v3(diff);
+ bigger = dist1;
+
+ sub_v3_v3v3(diff, efa->e2->v1->co, efa->e2->v2->co);
+ dist2 = len_v3(diff);
+ if (bigger < dist2) bigger = dist2;
+
+ sub_v3_v3v3(diff, efa->e3->v1->co, efa->e3->v2->co);
+ dist3 = len_v3(diff);
+ if (bigger < dist3) bigger = dist3;
+
+ s = (dist1 + dist2 + dist3) * 0.5f; //area =
sqrtf(s*(s-dist1)*(s-dist2)*(s-dist3)); r = area/s; /* incircle radius */
+ d = 2.f * sqrtf((s-dist1)*(s-dist2)*(s-dist3)/s);
+
+ if (d > detail){
+ //if (bigger == dist1) efa->e1->f |= SELECT;
+ //else if (bigger == dist2) efa->e2->f |= SELECT;
+ //else efa->e3->f |= SELECT;
+
+ if ((efa->v1->count <= edge_treshold) && (efa->v2->count <=
edge_treshold) && (efa->v3->count <= edge_treshold)){
+ efa->e1->f |= SELECT;
+ efa->e2->f |= SELECT;
+ efa->e3->f |= SELECT;
+ if (efa->e4) efa->e4->f |= SELECT;
+ }
+ }
+ } //if (efa->f & SELECT)
+ if ((efa->v1->count > edge_treshold) || (efa->v2->count >
edge_treshold) || (efa->v3->count > edge_treshold)){
+ float bigger = 0.f;
+ sub_v3_v3v3(diff, efa->e1->v1->co, efa->e1->v2->co);
+ dist1 = len_v3(diff);
+ bigger = dist1;
+
+ sub_v3_v3v3(diff, efa->e2->v1->co, efa->e2->v2->co);
+ dist2 = len_v3(diff);
+ if (bigger < dist2) bigger = dist2;
+
+ sub_v3_v3v3(diff, efa->e3->v1->co, efa->e3->v2->co);
+ dist3 = len_v3(diff);
+ if (bigger < dist3) bigger = dist3;
+
+ s = (dist1 + dist2 + dist3) * 0.5f; //area =
sqrtf(s*(s-dist1)*(s-dist2)*(s-dist3)); r = area/s;
+ d = 2.f * sqrtf((s-dist1)*(s-dist2)*(s-dist3)/s);
+
+ if (d > detail){
+ if (efa->v1->count > edge_treshold) { //efa->e2->f &= ~SELECT;
+ efa->e1->f |= SELECT;
+ efa->e3->f |= SELECT;
+ efa->e2->f &= ~SELECT;
+ }
+
+ if (efa->v2->count > edge_treshold) {
+ efa->e1->f |= SELECT;
+ efa->e2->f |= SELECT;
+ efa->e3->f &= ~SELECT;
+ }
+ if (efa->v3->count > edge_treshold) {
+ efa->e2->f |= SELECT;
+ efa->e3->f |= SELECT;
+ efa->e1->f &= ~SELECT;
+ }
+ } //if (d > detail)
+ } //if ((efa->v1->count > edge_treshold) || (efa->v2-> ....*/
+ } //for(efa= em->faces.first...
+} //*/
+
+DerivedMesh *uclay_dm_create_from_derived(struct UClayModifierData *ucmd,
int local_ucmd, DerivedMesh *dm,struct Object *ob,struct Scene
*scene,float radius, int useRenderParams,int isFinalCalc)
+{
+ EditMesh *em;
+ EditMeshDerivedMesh *emdm;
+ DerivedMesh *result;
+ EditVert *eve;
+ float detail = radius * ucmd->detail; //fix this parameter
+ int toteditface = 0, repeat = ucmd->relax;
+ Mesh *me = (Mesh *)ob->data;
+ int mark = 0, i = 0;
+ int edge_treshold = 9; //fator to trigger edge splitting
+
+ //LinkNode *listeditedges = NULL;
+ //LinkData *iter = NULL;
+
+ if (!me->edit_mesh)
+ make_editMesh(scene,ob);
+ em = me->edit_mesh;
+
+ /* em = (EditMesh *)ucmd->emCache;
+ if (!em) {
+ ucmd->emCache = (struct EditMesh *) MEM_callocN(sizeof(struct
EditMesh), "editmesh from derivedmesh");
+ em = (EditMesh *)ucmd->emCache;
+ make_editMesh_from_DerivedMesh(scene,ob,dm, em);
+ } // OK :) */
+
+
+ //select_edges_uclay(em, radius, detail, repeat, edge_treshold);
+ esubdivideflag_local(ob, em, SELECT,ucmd->smoothness,0,B_SMOOTH,1,
SUBDIV_CORNER_INNERVERT, 0);
+ //convert_to_triface_all(em,0); //find a way to allways enforce this
from subdivission
+ laplacian_relaxation(em, 0.5f, 0.1f, 0.1f, detail); //fix conflict with
esubd .. issues with flags
+
+ //recalc_editnormals(em);
+ //try to achieve even faces
+ //for (efa=em->faces.first;efa; efa =efa->next){
+ // if (efa->e1->f & SELECT)
+ //}
+
+ // we could combine any amount of editmesh tools here ;)!
+
+ //for (i=0; i<repeat; i++) {
+ // smooth_vertex_editmesh(ob,em); //OK
+ //}
+
+ /* clear selection */
+ //for (eve= em->verts.first; eve; eve= eve->next) eve->f &= ~SELECT;
+ //for (eed= em->edges.first; eed; eed= eed->next)
+ // eed->f &= ~SELECT;
+ EM_clear_flag_all(em, SELECT); //*/
+ for (eve= em->verts.first; eve; eve= eve->next) eve->f1 = 0; //smooth flag
+
+ result = getEditMeshDerivedMesh_uclay(em, ob, NULL); //OK
CDDM_from_mesh(me, ob);
+ emdm = (EditMeshDerivedMesh *)result;
+
+ /* build here the array from editfaces*/
+ //toteditface = emdm->numfaces;
+ //pbvh = emdm->pbvh;
+ //i = 0;
+ emdm->scene = scene;
+ emdm->ob = ob;
+
+ /* if(ob->sculpt && ob->sculpt->pbvh) {
+ if(!ob->sculpt->cache) {
+ BLI_pbvh_free(ob->sculpt->pbvh);
+ ob->sculpt->pbvh= NULL;
+ }
+ }
+
+// BLI_linklist_free(listeditedges,NULL); //*/
+ return result;
+}
Index: source/blender/blenkernel/intern/multires.c
===================================================================
--- source/blender/blenkernel/intern/multires.c (revision 32564)
+++ source/blender/blenkernel/intern/multires.c (working copy)
@@ -116,12 +116,26 @@
ccgdm->multires.modified = 1;
}
+//Mio, eventually moved
+static void uclay_dm_mark_as_modified(DerivedMesh *dm)
+{
+ EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *)dm;
+ emdm->modified = 1;
+}
+
void multires_mark_as_modified(Object *ob)
{
if(ob && ob->derivedFinal)
multires_dm_mark_as_modified(ob->derivedFinal);
}
+//mio Eventually moved
+void uclay_mark_as_modified(Object *ob)
+{
+ if(ob && ob->derivedFinal)
+ uclay_dm_mark_as_modified(ob->derivedFinal);
+}
+
void multires_force_update(Object *ob)
{
if(ob) {
@@ -137,6 +151,22 @@
}
}
+/* temporal here buy eventually movd toa correct place*/
+void uclay_force_update(Object *ob)
+{
+ if(ob) {
+ if(ob->derivedFinal) {
+ ob->derivedFinal->needsFree =1;
+ ob->derivedFinal->release(ob->derivedFinal);
+ ob->derivedFinal = NULL;
+ }
+ if(ob->sculpt && ob->sculpt->pbvh) {
+ BLI_pbvh_free(ob->sculpt->pbvh);
+ ob->sculpt->pbvh= NULL;
+ }
+ }
+}
+
void multires_force_external_reload(Object *ob)
{
Mesh *me = get_mesh(ob);
@@ -678,7 +708,7 @@
mmd = ccgdm->multires.mmd;
multires_set_tot_mdisps(me, mmd->totlvl);
CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
- mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
+ mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
if(mdisps) {
int lvl = ccgdm->multires.lvl;
@@ -782,7 +812,7 @@
DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd,
int local_mmd, DerivedMesh *dm, Object *ob,
int useRenderParams, int UNUSED(isFinalCalc))
{
- Mesh *me= ob->data;
+ Mesh *me= (Mesh *)ob->data;
DerivedMesh *result;
CCGDerivedMesh *ccgdm;
DMGridData **gridData, **subGridData;
@@ -811,16 +841,16 @@
gridSize = result->getGridSize(result);
gridData = result->getGridData(result);
- subGridData = MEM_callocN(sizeof(DMGridData*)*numGrids, "subGridData*");
+ subGridData = (DMGridData **)MEM_callocN(sizeof(DMGridData*)*numGrids,
"subGridData*");
for(i = 0; i < numGrids; i++) {
- subGridData[i] = MEM_callocN(sizeof(DMGridData)*gridSize*gridSize,
"subGridData");
+ subGridData[i] = (DMGridData
*)MEM_callocN(sizeof(DMGridData)*gridSize*gridSize, "subGridData");
memcpy(subGridData[i], gridData[i], sizeof(DMGridData)*gridSize*gridSize);
}
multires_set_tot_mdisps(me, mmd->totlvl);
CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
- multiresModifier_disp_run(result, ob->data, 0, 0, subGridData,
mmd->totlvl);
+ multiresModifier_disp_run(result, (Mesh *)ob->data, 0, 0, subGridData,
mmd->totlvl);
for(i = 0; i < numGrids; i++)
MEM_freeN(subGridData[i]);
@@ -1385,3 +1415,4 @@
me->mr= NULL;
}
+
Index: source/blender/blenkernel/intern/subsurf_ccg.c
===================================================================
--- source/blender/blenkernel/intern/subsurf_ccg.c (revision 32564)
+++ source/blender/blenkernel/intern/subsurf_ccg.c (working copy)
@@ -70,6 +70,7 @@
static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f);
static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm);
+static int edDM_use_uclay_pbvh(EditMeshDerivedMesh *emdm); //mio,
eventually moved
///
@@ -1971,8 +1972,8 @@
if(!ccgdm->multires.local_mmd &&
BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) <
0)
ccgdm->multires.mmd = NULL;
if(ccgdm->multires.mmd)
- ccgdm->multires.update(dm);
- }
+ ccgdm->multires.update(dm);
+ }
if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
@@ -1988,6 +1989,7 @@
MEM_freeN(ccgdm->faceMap);
MEM_freeN(ccgdm);
}
+
}
static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
@@ -2752,3 +2754,4 @@
dm->release(dm);
}
+
Index: source/blender/blenlib/BLI_editVert.h
===================================================================
--- source/blender/blenlib/BLI_editVert.h (revision 32564)
+++ source/blender/blenlib/BLI_editVert.h (working copy)
@@ -60,8 +60,19 @@
} tmp;
float no[3]; /*vertex normal */
float co[3]; /*vertex location */
+ float v; /* vertex speed */
short xs, ys; /* used to store a screenspace 2d projection of the verts */
+
+ float old_co[3]; /* original position */
+ float sum_b[3]; /* accumulated factor*/
+ float sum_co[3]; //HC relax
+ float p[3]; //HC relax
+ float b[3]; // HC relax
+ int count; /* number of neighbours */
+ float sum_dist; /* accumulated neighbours */
+ float w; /* accumulated weigth */
+
/* f stores selection eg. if (eve->f & SELECT) {...
h for hidden. if (!eve->h) {...
f1 and f2 can be used for temp data, clear them first*/
@@ -150,8 +161,8 @@
typedef struct EditMesh
{
ListBase verts, edges, faces;
- ListBase selected; /*EditSelections. Used to store the order in which
things are selected.*/
- HashEdge *hashedgetab;
+ ListBase selected; /*EditSelections. Used to store the order in which
things are selected.*/
+ HashEdge *hashedgetab;
/* this is for the editmesh_fastmalloc */
EditVert *allverts, *curvert;
Index: source/blender/blenlib/BLI_math_geom.h
===================================================================
--- source/blender/blenlib/BLI_math_geom.h (revision 32564)
+++ source/blender/blenlib/BLI_math_geom.h (working copy)
@@ -94,6 +94,8 @@
float v0[3], float v1[3], float v2[3], float *lambda, float *uv, float
threshold);
int isect_ray_tri_epsilon_v3(float p1[3], float d[3],
float v0[3], float v1[3], float v2[3], float *lambda, float *uv, float
epsilon);
+int fast_discard_tri(float center[3], float R, float v1[3], float v2[3],
float v3[3]);
+int FastRayTri(float orig[3], float dir[3], float v0[3], float v1[3],
float v2[3]);
/* point in polygon */
int isect_point_tri_v2(float p[2], float a[2], float b[2], float c[2]);
Index: source/blender/blenlib/BLI_pbvh.h
===================================================================
--- source/blender/blenlib/BLI_pbvh.h (revision 32564)
+++ source/blender/blenlib/BLI_pbvh.h (working copy)
@@ -32,7 +32,12 @@
struct PBVH;
struct PBVHNode;
struct ListBase;
+struct EditMesh;
+struct EditVert;
+struct EditFace;
+struct DMGridData;
+
typedef struct PBVH PBVH;
typedef struct PBVHNode PBVHNode;
@@ -53,11 +58,13 @@
PBVH *BLI_pbvh_new(void);
void BLI_pbvh_build_mesh(PBVH *bvh, struct MFace *faces, struct MVert
*verts,
int totface, int totvert);
+void BLI_pbvh_build_editmesh(PBVH *bvh, struct EditFace *editfaces,
struct EditVert *editverts, int toteditface, int toteditvert);
void BLI_pbvh_build_grids(PBVH *bvh, struct DMGridData **grids,
struct DMGridAdjacency *gridadj, int totgrid,
int gridsize, void **gridfaces);
void BLI_pbvh_free(PBVH *bvh);
+
/* Hierarchical Search in the BVH, two methods:
* for each hit calling a callback
* gather nodes in an array (easy to multithread) */
@@ -107,6 +114,7 @@
int *uniquevert, int *totvert);
void BLI_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node,
int **vert_indices, struct MVert **verts);
+void BLI_pbvh_node_get_editverts(PBVH *bvh, PBVHNode *node, int
*toteditvert);
void BLI_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3]);
void BLI_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float
bb_max[3]);
@@ -121,6 +129,7 @@
void BLI_pbvh_grids_update(PBVH *bvh, struct DMGridData **grids,
struct DMGridAdjacency *gridadj, void **gridfaces);
+
/* vertex deformer */
float (*BLI_pbvh_get_vertCos(struct PBVH *pbvh))[3];
void BLI_pbvh_apply_vertCos(struct PBVH *pbvh, float (*vertCos)[3]);
@@ -133,6 +142,7 @@
- allow the compiler to eliminate dead code and variables
- spend most of the time in the relatively simple inner loop */
+
#define PBVH_ITER_ALL 0
#define PBVH_ITER_UNIQUE 1
@@ -146,6 +156,10 @@
int gy;
int i;
+ /* EditMesh Mio*/
+ struct EditVert *editvert;
+ int toteditvert;
+
/* grid */
struct DMGridData **grids;
struct DMGridData *grid;
@@ -166,6 +180,89 @@
float *fno;
} PBVHVertexIter;
+/* Axis-aligned bounding box */
+typedef struct {
+ float bmin[3], bmax[3];
+} BB;
+
+/* Axis-aligned bounding box with centroid */
+typedef struct {
+ float bmin[3], bmax[3], bcentroid[3];
+} BBC;
+
+struct PBVHNode {
+ /* Opaque handle for drawing code */
+ void *draw_buffers;
+
+ int *vert_indices;
+
+ /* Voxel bounds */
+ BB vb;
+ BB orig_vb;
+
+ /* For internal nodes */
+ int children_offset;
+
+ /* Pointer into bvh prim_indices */
+ int *prim_indices;
+ int *face_vert_indices;
+
+ /* EditVert */
+ unsigned int toteditverts;
+ struct EditVert **editverts;
+
+ unsigned int totprim;
+ unsigned int uniq_verts, face_verts;
+
+ char flag;
+
+ float tmin; // used for raycasting, is how close bb is to the ray point
+
+ int proxy_count;
+ PBVHProxyNode* proxies;
+};
+/* Bitmap */
+typedef char* BLI_bitmap;
+
+struct PBVH {
+ PBVHNode *nodes;
+ int node_mem_count, totnode;
+
+ int *prim_indices;
+ int totprim;
+ int totvert;
+
+ int leaf_limit;
+
+ /* Mesh data */
+ struct MVert *verts;
+ struct MFace *faces;
+
+ /* Grid Data */
+ struct DMGridData **grids;
+ struct DMGridAdjacency *gridadj;
+ void **gridfaces;
+ int totgrid;
+ int gridsize;
+
+ /*EditMesh Data*/
+ struct EditFace **editfaces; /* not all editfaces, just node*/
+
+
+ /* Only used during BVH build and update,
+ don't need to remain valid after */
+ BLI_bitmap vert_bitmap;
+
+#ifdef PERFCNTRS
+ int perf_modified;
+#endif
+
+ /* flag are verts/faces deformed */
+ int deformed;
+};
+
+#define STACK_FIXED_DEPTH 100
+
#ifdef _MSC_VER
#pragma warning (disable:4127) // conditional expression is constant
#endif
@@ -174,22 +271,25 @@
{ \
struct DMGridData **grids; \
struct MVert *verts; \
- int *grid_indices, totgrid, gridsize, *vert_indices, uniq_verts,
totvert; \
+ int *grid_indices, totgrid, gridsize, *vert_indices, uniq_verts,
totvert, toteditvert; \
\
vi.grid= 0; \
vi.no= 0; \
vi.fno= 0; \
vi.mvert= 0; \
vi.skip= 0; \
+ vi.editvert= 0; \
\
BLI_pbvh_node_get_grids(bvh, node, &grid_indices, &totgrid, NULL,
&gridsize, &grids, NULL); \
BLI_pbvh_node_num_verts(bvh, node, &uniq_verts, &totvert); \
BLI_pbvh_node_get_verts(bvh, node, &vert_indices, &verts); \
+ BLI_pbvh_node_get_editverts(bvh, node, &toteditvert); \
\
vi.grids= grids; \
vi.grid_indices= grid_indices; \
vi.totgrid= (grids)? totgrid: 1; \
vi.gridsize= gridsize; \
+ vi.toteditvert= toteditvert; \
\
if(mode == PBVH_ITER_ALL) \
vi.totvert = totvert; \
@@ -226,13 +326,18 @@
vi.fno= vi.grid->no; \
vi.grid++; \
} \
+ else if (vi.toteditvert) { \
+ vi.editvert = node->editverts[vi.gx]; \
+ vi.co= vi.editvert->co; \
+ vi.fno= vi.editvert->no; \
+ } \
else { \
vi.mvert= &vi.mverts[vi.vert_indices[vi.gx]]; \
vi.co= vi.mvert->co; \
vi.no= vi.mvert->no; \
} \
-#define BLI_pbvh_vertex_iter_end \
+#define BLI_pbvh_vertex_iter_end(vi) \
} \
} \
}
@@ -247,3 +352,4 @@
#endif /* BLI_PBVH_H */
+
Index: source/blender/blenlib/intern/math_geom.c
===================================================================
--- source/blender/blenlib/intern/math_geom.c (revision 32564)
+++ source/blender/blenlib/intern/math_geom.c (working copy)
@@ -420,6 +420,31 @@
return 1;
}
+int fast_discard_tri(float center[3], float R, float v1[3], float v2[3],
float v3[3]){
+ float deltha1, deltha2;
+ deltha1 = center[0] - R;
+ if ((v1[0] < deltha1) && (v2[0] < deltha1) && (v3[0] < deltha1)) return 0;
+
+ deltha2 = center[0] + R;
+ if ((v1[0] > deltha2) && (v2[0] > deltha2) && (v3[0] > deltha2)) return 0;
+
+ //----discarding Y axis---------
+ deltha1 = center[1] - R;
+ if ((v1[1] < deltha1) && (v2[1] < deltha1) && (v3[1] < deltha1)) return 0;
+
+ deltha2 = center[1] + R;
+ if ((v1[1] > deltha2) && (v2[1] > deltha2) && (v3[1] > deltha2)) return 0;
+
+ //----discarding Z axis---------
+ deltha1 = center[2] - R;
+ if ((v1[2] < deltha1) && (v2[2] < deltha1) && (v3[2] < deltha1)) return 0;
+
+ deltha2 = center[2] + R;
+ if ((v1[2] > deltha2) && (v2[2] > deltha2) && (v3[2] > deltha2)) return 0;
+
+ return 1;
+}
+
/* moved from effect.c
test if the ray starting at p1 going in d direction intersects the
triangle v0..v2
return non zero if it does
@@ -459,12 +484,45 @@
return 1;
}
+//With Culling
+int FastRayTri(float orig[3], float dir[3], float v0[3], float v1[3],
float v2[3]){
+ float edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];
+ double det, inv_det, t, u, v;
+ //find vectors for two edges sharing vert
+ sub_v3_v3v3(edge1,v1,v2);
+ sub_v3_v3v3(edge2,v2,v0);
+
+ //begin calculating determinant also used to calculate U parameter
+ cross_v3_v3v3(pvec,dir,edge2);
+
+ //if determinant is near zero ray lies in plane of triangle
+ det = dot_v3v3(edge1, pvec);
+
+ if (det < 0.00001f) return 0;
+
+ //calculate distance from vertex to ray origin
+ sub_v3_v3v3(tvec,orig,v0);
+
+ //calculate U parameter and test bounds
+ u = dot_v3v3(tvec,pvec);
+ if ( u < 0.0f || u > det) return 0;
+
+
+ //prepare to test V parameter
+ cross_v3_v3v3(qvec,tvec,edge1);
+
+ //calculate V parameter and test bounds
+ v = dot_v3v3(dir,qvec);
+ if ( v < 0.0f || u + v > det) return 0;
+ return 1;
+ }
+
int isect_ray_tri_epsilon_v3(float p1[3], float d[3], float v0[3], float
v1[3], float v2[3], float *lambda, float *uv, float epsilon)
{
float p[3], s[3], e1[3], e2[3], q[3];
float a, f, u, v;
-
+
sub_v3_v3v3(e1, v1, v0);
sub_v3_v3v3(e2, v2, v0);
@@ -491,7 +549,7 @@
uv[1]= v;
}
- return 1;
+ return 1;
}
int isect_ray_tri_threshold_v3(float p1[3], float d[3], float v0[3],
float v1[3], float v2[3], float *lambda, float *uv, float threshold)
Index: source/blender/blenlib/intern/pbvh.c
===================================================================
--- source/blender/blenlib/intern/pbvh.c (revision 32564)
+++ source/blender/blenlib/intern/pbvh.c (working copy)
@@ -29,6 +29,7 @@
#include "BLI_math.h"
#include "BLI_ghash.h"
#include "BLI_pbvh.h"
+#include "BLI_editVert.h"
#include "BKE_DerivedMesh.h"
#include "BKE_mesh.h" /* for mesh_calc_normals */
@@ -38,11 +39,12 @@
#define LEAF_LIMIT 10000
+#include
"C:\Blender_Build\blenderSVN\source\blender\editors\include\ED_mesh.h"
+
//#define PERFCNTRS
-/* Bitmap */
-typedef char* BLI_bitmap;
+
BLI_bitmap BLI_bitmap_new(int tot)
{
return MEM_callocN((tot >> 3) + 1, "BLI bitmap");
@@ -63,79 +65,8 @@
b[index >> 3] &= ~(1 << (index & 7));
}
-/* Axis-aligned bounding box */
-typedef struct {
- float bmin[3], bmax[3];
-} BB;
-/* Axis-aligned bounding box with centroid */
-typedef struct {
- float bmin[3], bmax[3], bcentroid[3];
-} BBC;
-struct PBVHNode {
- /* Opaque handle for drawing code */
- void *draw_buffers;
-
- int *vert_indices;
-
- /* Voxel bounds */
- BB vb;
- BB orig_vb;
-
- /* For internal nodes */
- int children_offset;
-
- /* Pointer into bvh prim_indices */
- int *prim_indices;
- int *face_vert_indices;
-
- unsigned int totprim;
- unsigned int uniq_verts, face_verts;
-
- char flag;
-
- float tmin; // used for raycasting, is how close bb is to the ray point
-
- int proxy_count;
- PBVHProxyNode* proxies;
-};
-
-struct PBVH {
- PBVHNode *nodes;
- int node_mem_count, totnode;
-
- int *prim_indices;
- int totprim;
- int totvert;
-
- int leaf_limit;
-
- /* Mesh data */
- MVert *verts;
- MFace *faces;
-
- /* Grid Data */
- DMGridData **grids;
- DMGridAdjacency *gridadj;
- void **gridfaces;
- int totgrid;
- int gridsize;
-
- /* Only used during BVH build and update,
- don't need to remain valid after */
- BLI_bitmap vert_bitmap;
-
-#ifdef PERFCNTRS
- int perf_modified;
-#endif
-
- /* flag are verts/faces deformed */
- int deformed;
-};
-
-#define STACK_FIXED_DEPTH 100
-
typedef struct PBVHStack {
PBVHNode *node;
int revisiting;
@@ -222,7 +153,7 @@
BLI_pbvh_vertex_iter_begin(bvh, node, vd, PBVH_ITER_ALL) {
BB_expand(&vb, vd.co);
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
else {
BB_expand_with_bb(&vb,
@@ -383,6 +314,40 @@
BLI_ghash_free(map, NULL, NULL);
}
+static void build_editmesh_leaf_node(PBVH *bvh, PBVHNode *node){
+ int i, totface, toteditverts = 0;
+ int counter = 0;
+ GHash *gh;
+ GHashIterator* ghi;
+
+ gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp,
"editverts gh");
+
+ totface= node->totprim;
+
+ /* avoid duplicated editverts using a GHash */
+ for(i = 0; i < totface; i++) {
+ EditFace *f = bvh->editfaces[node->prim_indices[i]];
+
+ if (!BLI_ghash_haskey(gh,f->v1)) BLI_ghash_insert(gh, f->v1, NULL);
+ if (!BLI_ghash_haskey(gh,f->v2)) BLI_ghash_insert(gh, f->v2, NULL);
+ if (!BLI_ghash_haskey(gh,f->v3)) BLI_ghash_insert(gh, f->v3, NULL);
+ if (f->v4) if (!BLI_ghash_haskey(gh,f->v4)) BLI_ghash_insert(gh, f->v4,
NULL); //*/
+
+ }
+ toteditverts = BLI_ghash_size(gh);
+ node->toteditverts = toteditverts;
+ node->editverts = MEM_callocN(toteditverts * sizeof(EditVert *), "node
EditVert array");
+
+ ghi = BLI_ghashIterator_new(gh);
+ for(i = 0; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi),
i++){
+ node->editverts[i]=BLI_ghashIterator_getKey(ghi);
+ }
+
+ node->flag |= PBVH_UpdateDrawBuffers;
+ BLI_ghashIterator_free(ghi);
+ BLI_ghash_free(gh, NULL, NULL);
+}
+
static void build_grids_leaf_node(PBVH *bvh, PBVHNode *node)
{
if(!G.background) {
@@ -393,6 +358,7 @@
node->flag |= PBVH_UpdateDrawBuffers;
}
+
/* Recursively build a node in the tree
vb is the voxel box around all of the primitives contained in
@@ -428,8 +394,11 @@
if(bvh->faces)
build_mesh_leaf_node(bvh, bvh->nodes + node_index);
- else
+ else if (bvh->grids)
build_grids_leaf_node(bvh, bvh->nodes + node_index);
+ else if (bvh->editfaces)
+ build_editmesh_leaf_node(bvh, bvh->nodes + node_index);
+
bvh->nodes[node_index].orig_vb= bvh->nodes[node_index].vb;
/* Done with this subtree */
@@ -479,7 +448,7 @@
if(totprim != bvh->totprim) {
bvh->totprim = totprim;
if(bvh->nodes) MEM_freeN(bvh->nodes);
- if(bvh->prim_indices) MEM_freeN(bvh->prim_indices);
+ if(bvh->prim_indices) MEM_freeN(bvh->prim_indices);
bvh->prim_indices = MEM_callocN(sizeof(int) * totprim,
"bvh prim indices");
for(i = 0; i < totprim; ++i)
@@ -497,7 +466,8 @@
build_sub(bvh, 0, cb, prim_bbc, 0, totprim);
}
-/* Do a full rebuild with on Mesh data structure */
+
+/* Do a full rebuild with on Mesh data structure, reestructurar aqui*/
void BLI_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int
totface, int totvert)
{
BBC *prim_bbc = NULL;
@@ -514,7 +484,7 @@
/* For each face, store the AABB and the AABB centroid */
prim_bbc = MEM_mallocN(sizeof(BBC) * totface, "prim_bbc");
-
+
for(i = 0; i < totface; ++i) {
MFace *f = faces + i;
const int sides = f->v4 ? 4 : 3;
@@ -537,6 +507,67 @@
MEM_freeN(bvh->vert_bitmap);
}
+
+
+/* Do a full rebuild with on EditMesh data structure */
+void BLI_pbvh_build_editmesh(PBVH *bvh, EditFace *editfaces, EditVert
*editverts, int toteditface, int toteditvert)
+{
+ BBC *prim_bbc = NULL;
+ BB cb;
+ int i = 0;
+ EditFace *efa;
+
+ bvh->leaf_limit = LEAF_LIMIT;
+
+ BB_reset(&cb);
+
+ /* For each editface, store the AABB and the AABB centroid */
+ prim_bbc = (BBC *)MEM_mallocN(sizeof(BBC) * toteditface, "prim_bbc");
+
+ bvh->editfaces = (EditFace *)MEM_callocN(toteditface * sizeof(EditFace
*),"EditFace array");
+
+ for(efa= editfaces; efa; efa= efa->next){
+ BBC *bbc = prim_bbc + i;
+ BB_reset((BB*)bbc);
+
+ BB_expand((BB*)bbc, efa->v1->co);
+ BB_expand((BB*)bbc, efa->v2->co);
+ BB_expand((BB*)bbc, efa->v3->co);
+
+ if (efa->v4) BB_expand((BB*)bbc, efa->v4->co);
+
+ BBC_update_centroid(bbc);
+ BB_expand(&cb, bbc->bcentroid);
+ bvh->editfaces[i]= efa;
+ i++;
+ }
+
+ /* prim_bbc = (BBC *)MEM_mallocN(sizeof(BBC) * toteditvert, "prim_bbc");
+ i = 0;
+
+ for (eve = editverts; eve; eve = eve->next){
+ BBC *bbc = prim_bbc + i;
+ BB_reset((BB*)bbc);
+
+ BB_expand((BB*)bbc, eve->co);
+
+ BBC_update_centroid(bbc);
+ BB_expand(&cb, bbc->bcentroid);
+ ++i;
+ } //*/
+
+ if(toteditface)
+ pbvh_build(bvh, &cb, prim_bbc, toteditface);
+ //if(toteditvert)
+ // pbvh_build(bvh, &cb, prim_bbc, toteditvert);
+
+ MEM_freeN(prim_bbc);
+}
+
+void BLI_pbvh_update_editmesh(PBVH *bvh, EditFace *editfaces, EditVert
*editverts, int toteditface, int toteditvert){
+
+}
+
/* Do a full rebuild with on Grids data structure */
void BLI_pbvh_build_grids(PBVH *bvh, DMGridData **grids, DMGridAdjacency
*gridadj,
int totgrid, int gridsize, void **gridfaces)
@@ -579,7 +610,7 @@
PBVH *BLI_pbvh_new(void)
{
- PBVH *bvh = MEM_callocN(sizeof(PBVH), "pbvh");
+ PBVH *bvh = (PBVH *)MEM_callocN(sizeof(PBVH), "pbvh");
return bvh;
}
@@ -599,18 +630,23 @@
MEM_freeN(node->vert_indices);
if(node->face_vert_indices)
MEM_freeN(node->face_vert_indices);
+ if (node->editverts)
+ MEM_freeN(node->editverts);
}
}
if (bvh->deformed) {
if (bvh->verts) {
/* if pbvh was deformed, new memory was allocated for verts/faces --
free it */
-
MEM_freeN(bvh->verts);
- MEM_freeN(bvh->faces);
- }
+ MEM_freeN(bvh->faces);
+ }
}
+ if (bvh->editfaces){
+ MEM_freeN(bvh->editfaces);
+ }
+
MEM_freeN(bvh->nodes);
MEM_freeN(bvh->prim_indices);
MEM_freeN(bvh);
@@ -890,12 +926,97 @@
static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
int totnode, float (*face_nors)[3])
{
+ EditVert *eve;
float (*vnor)[3];
int n;
if(bvh->grids)
return;
+ if (bvh->editfaces){
+ return;
+ /* vnor= MEM_callocN(sizeof(float)*3*bvh->toteditvert, "bvh temp vnors");
+ #pragma omp parallel for private(n) schedule(static)
+ for(n = 0; n < totnode; n++) {
+ PBVHNode *node= nodes[n];
+
+ if((node->flag & PBVH_UpdateNormals)) {
+ int i, j, toteditface, *faces;
+
+ faces= node->prim_indices;
+ toteditface= node->totprim;
+
+ for(i = 0; i < toteditface; ++i) {
+ EditFace *f= bvh->editfaces[faces[i]];
+ float fn[3];
+ unsigned int *fv = &f->v1;
+ int sides= (f->v4)? 4: 3;
+
+ if(f->v4)
+ normal_quad_v3(fn, f->v1->co, f->v2->co,
+ f->v3->co, f->v4->co);
+ else
+ normal_tri_v3(fn, f->v1->co, f->v2->co,
+ f->v3->co);
+
+ for(j = 0; j < sides; ++j) {
+ int v= fv[j];
+
+ //if(bvh->editverts[v].flag & ME_VERT_PBVH_UPDATE) {
+ /* this seems like it could be very slow but profile
+ does not show this, so just leave it for now?
+ #pragma omp atomic
+ vnor[v][0] += fn[0];
+ #pragma omp atomic
+ vnor[v][1] += fn[1];
+ #pragma omp atomic
+ vnor[v][2] += fn[2];
+ //}
+ }
+
+ if(face_nors)
+ copy_v3_v3(face_nors[faces[i]], fn);
+ }
+ }
+ }
+ //----------
+ #pragma omp parallel for private(n) schedule(static)
+ for(n = 0; n < totnode; n++) {
+ PBVHNode *node= nodes[n];
+
+ if(node->flag & PBVH_UpdateNormals) {
+ int i, *verts, totvert;
+
+ verts= node->editvert_indices;
+ totvert= node->toteditverts;
+
+ for(i = 0; i < totvert; ++i) {
+ const int v = verts[i];
+ EditVert *eve= &bvh->editverts[v];
+
+ //if(eve->flag & ME_VERT_PBVH_UPDATE) {
+ float no[3];
+
+ copy_v3_v3(no, vnor[v]);
+ normalize_v3(no);
+
+ eve->no[0] = no[0];
+ eve->no[1] = no[1];
+ eve->no[2] = no[2];
+
+ //eve->flag &= ~ME_VERT_PBVH_UPDATE;
+ //}
+ }
+
+ node->flag &= ~PBVH_UpdateNormals;
+ }
+ }
+
+ MEM_freeN(vnor);
+ return;
+ //-----------//*/
+ }
+
/* could be per node to save some memory, but also means
we have to store for each vertex which node it is in */
vnor= MEM_callocN(sizeof(float)*3*bvh->totvert, "bvh temp vnors");
@@ -1020,7 +1141,7 @@
for(n = 0; n < totnode; n++) {
node= nodes[n];
- if(node->flag & PBVH_UpdateDrawBuffers) {
+ if(node->flag & PBVH_UpdateDrawBuffers) { //Mio, put here
bvh->editverts code
if(bvh->grids) {
GPU_update_grid_buffers(node->draw_buffers,
bvh->grids,
@@ -1029,6 +1150,14 @@
bvh->gridsize,
smooth);
}
+ else if (bvh->editfaces){ //Mio
+ //GPU_update_editmesh_buffers(node->draw_buffers,
+ // bvh->grids,
+ // node->vert_indices,
+ // node->toteditvert,
+ // bvh->gridsize,
+ // smooth);
+ }
else {
GPU_update_mesh_buffers(node->draw_buffers,
bvh->verts,
@@ -1184,10 +1313,14 @@
if(totvert) *totvert= node->totprim*bvh->gridsize*bvh->gridsize;
if(uniquevert) *uniquevert= *totvert;
}
- else {
+ else if (bvh->verts){
if(totvert) *totvert= node->uniq_verts + node->face_verts;
if(uniquevert) *uniquevert= node->uniq_verts;
}
+ else if (bvh->editfaces){
+ if (totvert) *totvert = node->toteditverts;
+ if (uniquevert) *uniquevert = *totvert;
+ }
}
void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int
**grid_indices, int *totgrid, int *maxgrid, int *gridsize, DMGridData
***griddata, DMGridAdjacency **gridadj)
@@ -1210,6 +1343,16 @@
}
}
+void BLI_pbvh_node_get_editverts(PBVH *bvh, PBVHNode *node, int
*toteditvert)
+{
+ if(bvh->editfaces) {
+ if (toteditvert) *toteditvert = node->toteditverts;
+ }
+ else {
+ if (toteditvert) *toteditvert = 0;
+ }
+}
+
void BLI_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
{
copy_v3_v3(bb_min, node->vb.bmin);
@@ -1311,7 +1454,6 @@
float *fdist)
{
float dist;
-
if ((isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t1, t2,
&dist, NULL, 0.1f) && dist < *fdist) ||
(t3 && isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t2,
t3, &dist, NULL, 0.1f) && dist < *fdist))
{
@@ -1358,7 +1500,7 @@
}
}
}
- else {
+ else if (bvh->grids){
int totgrid= node->totprim;
int gridsize= bvh->gridsize;
int i, x, y;
@@ -1393,8 +1535,37 @@
origco += gridsize*gridsize;
}
}
-
- return hit;
+ else if (bvh->editfaces){
+ int toteditface= node->totprim;
+ int *faces= node->prim_indices;
+ int i= 0;
+ int isect;
+
+ for(i = 0; i < toteditface; i++) {
+ EditFace *f = bvh->editfaces[faces[i]];
+ f->f = 0; /* first clear UClay flags */
+ isect =0;
+ if(origco) {
+ /* intersect with backuped original coordinates
+ hit |= ray_face_intersection(ray_start, ray_normal,
+ origco[face_verts[i*4+0]],
+ origco[face_verts[i*4+1]],
+ origco[face_verts[i*4+2]],
+ f->v4? origco[face_verts[i*4+3]]: NULL,
+ dist); */
+ //Mio, to be implemented yet
+ }
+ else {
+ /* intersect with current coordinates, here implement for local faces
only not all */
+ isect = ray_face_intersection(ray_start, ray_normal, f->v1->co,
f->v2->co, f->v3->co, f->v4 ? f->v4->co : NULL, dist);
+ hit |= isect;
+ if (isect) {
+ if (dot_v3v3(ray_normal,f->n) < 0.f) f->f |= 1; /* only detect and
subdivide front faces */ //
+ }
+ }
+ }
+ }
+ return hit;
}
//#include <GL/glew.h>
@@ -1481,6 +1652,7 @@
bvh->gridfaces= gridfaces;
}
+
float (*BLI_pbvh_get_vertCos(PBVH *pbvh))[3]
{
int a;
@@ -1553,8 +1725,10 @@
if (bvh->grids)
totverts = node->totprim*bvh->gridsize*bvh->gridsize;
- else
+ else if (bvh->verts)
totverts = node->uniq_verts;
+ else if (bvh->editfaces)
+ totverts = node->toteditverts;
node->proxies[index].co= MEM_callocN(sizeof(float[3])*totverts,
"PBVHNodeProxy.co");
}
Index: source/blender/editors/include/ED_mesh.h
===================================================================
--- source/blender/editors/include/ED_mesh.h (revision 32564)
+++ source/blender/editors/include/ED_mesh.h (working copy)
@@ -102,6 +102,10 @@
void ED_spacetypes_init(void);
void ED_keymap_mesh(struct wmKeyConfig *keyconf);
+void make_editMeshDM(struct Scene *scene, struct Object *ob, struct
EditMesh *em);
+void make_editMesh_from_DerivedMesh(struct Scene *scene,struct Object
*ob,struct DerivedMesh *dm,struct EditMesh *em);
+void load_editMesh_external(struct Scene *scene,struct Object
*ob,struct EditMesh *em);
+void make_editmesh_arrays(struct EditMesh *em,struct MVert
*mvert,struct MFace *mface);
void make_editMesh(struct Scene *scene, struct Object *ob);
void load_editMesh(struct Scene *scene, struct Object *ob);
void remake_editMesh(struct Scene *scene, struct Object *ob);
@@ -230,9 +234,140 @@
int ED_mesh_color_add(struct bContext *C, struct Scene *scene, struct
Object *ob, struct Mesh *me, const char *name, int active_set);
int ED_mesh_color_remove(struct bContext *C, struct Object *ob, struct
Mesh *me);
+
+struct bContext;
+struct wmOperatorType;
+struct wmOperator;
+
+
+#define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float));
+
+/* ******************** editface.c */
+
+int edgetag_context_check(struct Scene *scene, struct EditEdge *eed);
+void edgetag_context_set(struct Scene *scene,struct EditEdge *eed, int val);
+int edgetag_shortest_path(struct Scene *scene,struct EditMesh *em,struct
EditEdge *source,struct EditEdge *target);
+
+/* ******************* editmesh.c */
+
+extern void free_editvert(struct EditMesh *em,struct EditVert *eve);
+extern void free_editedge(struct EditMesh *em,struct EditEdge *eed);
+extern void free_editface(struct EditMesh *em,struct EditFace *efa);
+void free_editMesh(struct EditMesh *em);
+
+extern void free_vertlist(struct EditMesh *em,struct ListBase *edve);
+extern void free_edgelist(struct EditMesh *em,struct ListBase *lb);
+extern void free_facelist(struct EditMesh *em,struct ListBase *lb);
+
+extern void remedge(struct EditMesh *em,struct EditEdge *eed);
+
+extern struct EditVert *addvertlist(struct EditMesh *em, float *vec,
struct EditVert *example);
+extern struct EditEdge *addedgelist(struct EditMesh *em, struct EditVert
*v1, struct EditVert *v2, struct EditEdge *example);
+extern struct EditFace *addfacelist(struct EditMesh *em, struct EditVert
*v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct
EditFace *example, struct EditFace *exampleEdges);
+extern struct EditEdge *findedgelist(struct EditMesh *em, struct EditVert
*v1, struct EditVert *v2);
+
+void em_setup_viewcontext(struct bContext *C,struct ViewContext *vc);
+/* ******************* editmesh_lib.c */
+void EM_stats_update(struct EditMesh *em);
+
+extern void EM_fgon_flags(struct EditMesh *em);
+extern void EM_hide_reset(struct EditMesh *em);
+
+extern int faceselectedOR(struct EditFace *efa, int flag);
+extern int faceselectedAND(struct EditFace *efa, int flag);
+
+void EM_remove_selection(struct EditMesh *em, void *data, int type);
+void EM_clear_flag_all(struct EditMesh *em, int flag);
+void EM_set_flag_all(struct EditMesh *em, int flag);
+void EM_set_flag_all_selectmode(struct EditMesh *em, int flag);
+
+void EM_data_interp_from_verts(struct EditMesh *em,struct EditVert
*v1,struct EditVert *v2,struct EditVert *eve, float fac);
+void EM_data_interp_from_faces(struct EditMesh *em,struct EditFace
*efa1,struct EditFace *efa2,struct EditFace *efan, int i1, int i2, int i3,
int i4);
+
+int EM_nvertices_selected(struct EditMesh *em);
+int EM_nedges_selected(struct EditMesh *em);
+int EM_nfaces_selected(struct EditMesh *em);
+
+float EM_face_perimeter(struct EditFace *efa);
+
+void EM_store_selection(struct EditMesh *em, void *data, int type);
+
+extern struct EditFace *exist_face(struct EditMesh *em,struct EditVert
*v1,struct EditVert *v2,struct EditVert *v3,struct EditVert *v4);
+extern void flipface(struct EditMesh *em,struct EditFace *efa); // flips
for normal direction
+extern int compareface(struct EditFace *vl1,struct EditFace *vl2);
+
+/* flag for selection bits, *nor will be filled with normal for extrusion
constraint */
+/* return value defines if such normal was set */
+extern short extrudeflag_face_indiv(struct EditMesh *em, short flag,
float *nor);
+extern short extrudeflag_verts_indiv(struct EditMesh *em, short flag,
float *nor);
+extern short extrudeflag_edges_indiv(struct EditMesh *em, short flag,
float *nor);
+extern short extrudeflag_vert(struct Object *obedit,struct EditMesh *em,
short flag, float *nor, int all);
+extern short extrudeflag(struct Object *obedit,struct EditMesh *em, short
flag, float *nor, int all);
+
+extern void adduplicateflag(struct EditMesh *em, int flag);
+extern void delfaceflag(struct EditMesh *em, int flag);
+
+extern void rotateflag(struct EditMesh *em, short flag, float *cent,
float rotmat[][3]);
+extern void translateflag(struct EditMesh *em, short flag, float *vec);
+
+
+extern struct EditFace *EM_face_from_faces(struct EditMesh *em, struct
EditFace *efa1,
+ struct EditFace *efa2, int i1, int i2, int i3, int i4);
+
+extern int EM_view3d_poll(struct bContext *C);
+
+/* ******************* editmesh_loop.c */
+
+#define LOOP_SELECT 1
+#define LOOP_CUT 2
+extern struct EditEdge *findnearestedge(struct ViewContext *vc, int *dist);
+extern void EM_automerge(struct Scene *scene,struct Object *obedit, int
update);
+void editmesh_select_by_material(struct EditMesh *em, int index);
+void EM_recalc_normal_direction(struct EditMesh *em, int inside, int
select); /* makes faces righthand turning */
+void EM_select_more(struct EditMesh *em);
+void selectconnected_mesh_all(struct EditMesh *em);
+void faceloop_select(struct EditMesh *em,struct EditEdge *startedge, int
select);
+
+/**
+ * findnearestvert
+ *
+ * dist (in/out): minimal distance to the nearest and at the end, actual
distance
+ * sel: selection bias
+ * if SELECT, selected vertice are given a 5 pixel bias to make them
farter than unselect verts
+ * if 0, unselected vertice are given the bias
+ * strict: if 1, the vertice corresponding to the sel parameter are
ignored and not just biased
+ */
+extern struct EditVert *findnearestvert(struct ViewContext *vc, int
*dist, short sel, short strict);
+
+
+/* ******************* editmesh_tools.c */
+
+#define SUBDIV_SELECT_ORIG 0
+#define SUBDIV_SELECT_INNER 1
+#define SUBDIV_SELECT_INNER_SEL 2
+#define SUBDIV_SELECT_LOOPCUT 3
+
+/* edge subdivide corner cut types */
+#define SUBDIV_CORNER_PATH 0
+#define SUBDIV_CORNER_INNERVERT 1
+#define SUBDIV_CORNER_FAN 2
+
+
+void join_triangles(struct EditMesh *em);
+int removedoublesflag(struct EditMesh *em, short flag, short automerge,
float limit); /* return amount */
+void esubdivideflag(struct Object *obedit,struct EditMesh *em, int flag,
float smooth, float fractal, int beautify, int numcuts, int
corner_pattern, int seltype);
+void esubdivideflag_local(struct Object *obedit,struct EditMesh *em, int
flag, float smooth, float fractal, int beautify, int numcuts, int
corner_pattern, int seltype);
+int smooth_vertex_editmesh(struct Object *obedit,struct EditMesh *em);
+void beautify_fill(struct EditMesh *em);
+void convert_to_triface_all(struct EditMesh *em, int direction);
+void fill_mesh(struct EditMesh *em);
+void addedgeface_mesh_uclay(struct EditMesh *em);
+
#ifdef __cplusplus
}
#endif
+
#endif /* ED_MESH_H */
+
Index: source/blender/editors/mesh/editmesh.c
===================================================================
--- source/blender/editors/mesh/editmesh.c (revision 32564)
+++ source/blender/editors/mesh/editmesh.c (working copy)
@@ -914,6 +914,431 @@
}
}
+/* turns Mesh into editmesh */
+void make_editMeshDM(Scene *scene, Object *ob,struct EditMesh *em)
+{
+ Mesh *me= ob->data;
+ MFace *mface;
+ MVert *mvert;
+ MSelect *mselect;
+ KeyBlock *actkey;
+ EditVert *eve, **evlist, *eve1, *eve2, *eve3, *eve4;
+ EditFace *efa, *efa_last_sel= NULL;
+ EditEdge *eed;
+ EditSelection *ese;
+ float *co, (*keyco)[3]= NULL;
+ int tot, a, eekadoodle= 0;
+
+ em->selectmode= scene->toolsettings->selectmode; // warning needs to be
synced
+ em->act_face = NULL;
+ em->totvert= tot= me->totvert;
+ em->totedge= me->totedge;
+ em->totface= me->totface;
+
+ if(tot==0) {
+ return;
+ }
+
+ if(ob->actcol > 0)
+ em->mat_nr= ob->actcol-1;
+
+ /* initialize fastmalloc for editmesh */
+ init_editmesh_fastmalloc(em, me->totvert, me->totedge, me->totface);
+
+ actkey = ob_get_keyblock(ob);
+ if(actkey) {
+ /* undo-ing in past for previous editmode sessions gives corrupt
'keyindex' values */
+ undo_editmode_clear();
+ keyco= actkey->data;
+ em->shapenr= ob->shapenr;
+ }
+
+ /* make editverts */
+ CustomData_copy(&me->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
+ mvert= me->mvert;
+
+ evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist");
+ for(a=0; a<tot; a++, mvert++) {
+
+ co= mvert->co;
+
+ /* edit the shape key coordinate if available */
+ if(keyco && a < actkey->totelem)
+ co= keyco[a];
+
+ eve= addvertlist(em, co, NULL);
+ evlist[a]= eve;
+
+ /* face select sets selection in next loop */
+ if(!paint_facesel_test(ob))
+ eve->f |= (mvert->flag & 1);
+
+ if (mvert->flag & ME_HIDE) eve->h= 1;
+ eve->no[0]= mvert->no[0]/32767.0;
+ eve->no[1]= mvert->no[1]/32767.0;
+ eve->no[2]= mvert->no[2]/32767.0;
+
+ eve->bweight= ((float)mvert->bweight)/255.0f;
+
+ /* lets overwrite the keyindex of the editvert
+ * with the order it used to be in before
+ * editmode
+ */
+ eve->keyindex = a;
+
+ CustomData_to_em_block(&me->vdata, &em->vdata, a, &eve->data);
+ }
+
+ if(actkey && actkey->totelem!=me->totvert);
+ else {
+ MEdge *medge= me->medge;
+
+ CustomData_copy(&me->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
+ /* make edges */
+ for(a=0; a<me->totedge; a++, medge++) {
+ eed= addedgelist(em, evlist[medge->v1], evlist[medge->v2], NULL);
+ /* eed can be zero when v1 and v2 are identical, dxf import does
this... */
+ if(eed) {
+ eed->crease= ((float)medge->crease)/255.0f;
+ eed->bweight= ((float)medge->bweight)/255.0f;
+
+ if(medge->flag & ME_SEAM) eed->seam= 1;
+ if(medge->flag & ME_SHARP) eed->sharp = 1;
+ if(medge->flag & SELECT) eed->f |= SELECT;
+ if(medge->flag & ME_FGON) eed->h= EM_FGON; // 2 different defines!
+ if(medge->flag & ME_HIDE) eed->h |= 1;
+ if(em->selectmode==SCE_SELECT_EDGE)
+ EM_select_edge(eed, eed->f & SELECT); // force edge selection to
vertices, seems to be needed ...
+ CustomData_to_em_block(&me->edata,&em->edata, a, &eed->data);
+ }
+ }
+
+ CustomData_copy(&me->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
+
+ /* make faces */
+ mface= me->mface;
+
+ for(a=0; a<me->totface; a++, mface++) {
+ eve1= evlist[mface->v1];
+ eve2= evlist[mface->v2];
+ if(!mface->v3) eekadoodle= 1;
+ eve3= evlist[mface->v3];
+ if(mface->v4) eve4= evlist[mface->v4]; else eve4= NULL;
+
+ efa= addfacelist(em, eve1, eve2, eve3, eve4, NULL, NULL);
+
+ if(efa) {
+ CustomData_to_em_block(&me->fdata, &em->fdata, a, &efa->data);
+
+ efa->mat_nr= mface->mat_nr;
+ efa->flag= mface->flag & ~ME_HIDE;
+
+ /* select and hide face flag */
+ if(mface->flag & ME_HIDE) {
+ efa->h= 1;
+ } else {
+ if (a==me->act_face) {
+ EM_set_actFace(em, efa);
+ }
+
+ /* dont allow hidden and selected */
+ if(mface->flag & ME_FACE_SEL) {
+ efa->f |= SELECT;
+
+ if(paint_facesel_test(ob)) {
+ EM_select_face(efa, 1); /* flush down */
+ }
+
+ efa_last_sel= efa;
+ }
+ }
+ }
+ }
+ }
+
+ if(EM_get_actFace(em, 0)==NULL && efa_last_sel) {
+ EM_set_actFace(em, efa_last_sel);
+ }
+
+ if(eekadoodle)
+ error("This Mesh has old style edgecodes, please put it in the
bugtracker!");
+
+ MEM_freeN(evlist);
+
+ end_editmesh_fastmalloc(); // resets global function pointers
+
+ if(me->mselect){
+ //restore editselections
+ EM_init_index_arrays(em, 1,1,1);
+ mselect = me->mselect;
+
+ for(a=0; a<me->totselect; a++, mselect++){
+ /*check if recorded selection is still valid, if so copy into editmesh*/
+ if( (mselect->type == EDITVERT && me->mvert[mselect->index].flag &
SELECT) || (mselect->type == EDITEDGE && me->medge[mselect->index].flag &
SELECT) || (mselect->type == EDITFACE && me->mface[mselect->index].flag &
ME_FACE_SEL) ){
+ ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
+ ese->type = mselect->type;
+ if(ese->type == EDITVERT) ese->data =
EM_get_vert_for_index(mselect->index); else
+ if(ese->type == EDITEDGE) ese->data =
EM_get_edge_for_index(mselect->index); else
+ if(ese->type == EDITFACE) ese->data =
EM_get_face_for_index(mselect->index);
+ BLI_addtail(&(em->selected),ese);
+ }
+ }
+ EM_free_index_arrays();
+ }
+ /* this creates coherent selections. also needed for older files */
+ EM_selectmode_set(em);
+ /* paranoia check to enforce hide rules */
+ EM_hide_reset(em);
+ /* sets helper flags which arent saved */
+ EM_fgon_flags(em);
+
+ if (EM_get_actFace(em, 0)==NULL) {
+ EM_set_actFace(em, em->faces.first ); /* will use the first face, this
is so we alwats have an active face */
+ }
+
+}
+
+/* turns DerivedMesh into EditMesh */
+void make_editMesh_from_DerivedMesh(struct Scene *scene,struct Object
*ob,struct DerivedMesh *dm, struct EditMesh *em)
+{
+ //Mesh *me= ob->data;
+ MFace *mface;
+ MVert *mvert;
+ KeyBlock *actkey;
+ EditVert *eve, **evlist, *eve1, *eve2, *eve3, *eve4;
+ EditFace *efa, *efa_last_sel= NULL;
+ EditEdge *eed;
+ float *co, (*keyco)[3]= NULL;
+ int tot, a, totvert,totedge,totface, eekadoodle= 0;
+
+ totvert = dm->getNumVerts(dm);
+ totedge = dm->getNumEdges(dm);
+ totface = dm->getNumFaces(dm);
+
+ em->selectmode= scene->toolsettings->selectmode; // warning needs to be
synced
+ em->act_face = NULL;
+ em->totvert= tot= dm->getNumVerts(dm);
+ em->totedge= dm->getNumEdges(dm);
+ em->totface= dm->getNumFaces(dm);
+
+
+ if(tot==0) {
+ return;
+ }
+
+ if(ob->actcol > 0)
+ em->mat_nr= ob->actcol-1;
+
+ /* initialize fastmalloc for editmesh */
+ init_editmesh_fastmalloc(em, totvert, totedge, totface);
+
+ actkey = ob_get_keyblock(ob);
+ if(actkey) {
+ /* undo-ing in past for previous editmode sessions gives corrupt
'keyindex' values */
+ undo_editmode_clear();
+ keyco= actkey->data;
+ em->shapenr= ob->shapenr;
+ }
+
+ /* make editverts */
+ CustomData_copy(&(dm->vertData), &em->vdata, CD_MASK_EDITMESH,
CD_CALLOC, 0); //Aqui?
+ mvert= dm->getVertArray(dm); //Aqui
+
+ evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist");
+ for(a=0; a<tot; a++, mvert++) {
+
+ co= mvert->co;
+
+ /* edit the shape key coordinate if available */
+ if(keyco && a < actkey->totelem)
+ co= keyco[a];
+
+ eve= addvertlist(em, co, NULL);
+ evlist[a]= eve;
+
+ /* face select sets selection in next loop */
+ if(!paint_facesel_test(ob))
+ eve->f |= (mvert->flag & 1);
+
+ if (mvert->flag & ME_HIDE) eve->h= 1;
+ eve->no[0]= mvert->no[0]/32767.0;
+ eve->no[1]= mvert->no[1]/32767.0;
+ eve->no[2]= mvert->no[2]/32767.0;
+
+ eve->bweight= ((float)mvert->bweight)/255.0f;
+
+ /* lets overwrite the keyindex of the editvert
+ * with the order it used to be in before
+ * editmode
+ */
+ eve->keyindex = a;
+
+ CustomData_to_em_block(&(dm->vertData), &em->vdata, a, &eve->data); //Aqui
+ }
+
+ if(actkey && actkey->totelem!=totvert); //Aqui
+ else {
+ MEdge *medge= dm->getEdgeArray(dm); //Aqui
+
+ CustomData_copy(&(dm->edgeData), &em->edata, CD_MASK_EDITMESH,
CD_CALLOC, 0); //Aqui
+ /* make edges */
+ for(a=0; a<totedge; a++, medge++) { //Aqui
+ eed= addedgelist(em, evlist[medge->v1], evlist[medge->v2], NULL);
+ /* eed can be zero when v1 and v2 are identical, dxf import does
this... */
+ if(eed) {
+ eed->crease= ((float)medge->crease)/255.0f;
+ eed->bweight= ((float)medge->bweight)/255.0f;
+
+ if(medge->flag & ME_SEAM) eed->seam= 1;
+ if(medge->flag & ME_SHARP) eed->sharp = 1;
+ if(medge->flag & SELECT) eed->f |= SELECT;
+ if(medge->flag & ME_FGON) eed->h= EM_FGON; // 2 different defines!
+ if(medge->flag & ME_HIDE) eed->h |= 1;
+ if(em->selectmode==SCE_SELECT_EDGE)
+ EM_select_edge(eed, eed->f & SELECT); // force edge selection to
vertices, seems to be needed ...
+ CustomData_to_em_block(&(dm->edgeData),&em->edata, a, &eed->data);
//Aqui
+ }
+ }
+
+ CustomData_copy(&(dm->faceData), &em->fdata, CD_MASK_EDITMESH,
CD_CALLOC, 0); //Aqui
+
+ /* make faces */
+ mface= dm->getFaceArray(dm); //Aqui
+
+ for(a=0; a<totface; a++, mface++) { //Aqui
+ eve1= evlist[mface->v1];
+ eve2= evlist[mface->v2];
+ if(!mface->v3) eekadoodle= 1;
+ eve3= evlist[mface->v3];
+ if(mface->v4) eve4= evlist[mface->v4]; else eve4= NULL;
+
+ efa= addfacelist(em, eve1, eve2, eve3, eve4, NULL, NULL);
+
+ if(efa) {
+ CustomData_to_em_block(&(dm->faceData), &em->fdata, a, &efa->data);
//Aqui
+
+ efa->mat_nr= mface->mat_nr;
+ efa->flag= mface->flag & ~ME_HIDE;
+
+ /* select and hide face flag */
+ if(mface->flag & ME_HIDE) {
+ efa->h= 1;
+ } else {
+ //if (a==me->act_face) {
+ // EM_set_actFace(em, efa);
+ //}
+
+ /* dont allow hidden and selected */
+ if(mface->flag & ME_FACE_SEL) {
+ efa->f |= SELECT;
+
+ if(paint_facesel_test(ob)) {
+ EM_select_face(efa, 1); /* flush down */
+ }
+
+ efa_last_sel= efa;
+ }
+ }
+ }
+ }
+ }
+
+ if(EM_get_actFace(em, 0)==NULL && efa_last_sel) {
+ EM_set_actFace(em, efa_last_sel);
+ }
+
+ if(eekadoodle)
+ error("This Mesh has old style edgecodes, please put it in the
bugtracker!");
+
+ MEM_freeN(evlist);
+
+ end_editmesh_fastmalloc(); // resets global function pointers
+
+ /*if(me->mselect){ //Aqui
+ //restore editselections
+ EM_init_index_arrays(em, 1,1,1);
+ mselect = me->mselect; //Aqui
+
+ for(a=0; a<me->totselect; a++, mselect++){ //Aqui
+ /*check if recorded selection is still valid, if so copy into
editmesh/ //Aqui
+ if( (mselect->type == EDITVERT && me->mvert[mselect->index].flag &
SELECT) || (mselect->type == EDITEDGE && me->medge[mselect->index].flag &
SELECT) || (mselect->type == EDITFACE && me->mface[mselect->index].flag &
ME_FACE_SEL) ){
+ ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
+ ese->type = mselect->type;
+ if(ese->type == EDITVERT) ese->data =
EM_get_vert_for_index(mselect->index); else
+ if(ese->type == EDITEDGE) ese->data =
EM_get_edge_for_index(mselect->index); else
+ if(ese->type == EDITFACE) ese->data =
EM_get_face_for_index(mselect->index);
+ BLI_addtail(&(em->selected),ese);
+ }
+ }
+ EM_free_index_arrays();
+ }
+ /* this creates coherent selections. also needed for older files */
+ EM_selectmode_set(em);
+ /* paranoia check to enforce hide rules */
+ EM_hide_reset(em);
+ /* sets helper flags which arent saved */
+ EM_fgon_flags(em);
+
+ if (EM_get_actFace(em, 0)==NULL) {
+ EM_set_actFace(em, em->faces.first ); /* will use the first face, this
is so we alwats have an active face */
+ }
+
+}
+
+void make_editmesh_arrays(EditMesh *em, MVert *mvert, MFace *mface){
+ MFace *mfaceindex;
+ MVert *mvertindex;
+ EditFace *efa;
+ float nor[3];
+
+ int i =0;
+ int a= 0;
+
+ EditVert *eve = em->verts.first;
+ while(eve) {
+ mvertindex = &((MVert *) mvert)[i];
+ VECCOPY(mvertindex->co, eve->co);
+
+ mvertindex->mat_nr= 32767; /* what was this for, halos? */
+
+ /* vertex normal */
+ VECCOPY(nor, eve->no);
+ mul_v3_fl(nor, 32767.0);
+ VECCOPY(mvertindex->no, nor);
+
+ //eve->tmp.l = a++; /* counter */
+
+ mvertindex->flag= 0;
+ mvertindex->flag |= (eve->f & SELECT);
+ if (eve->h) mvertindex->flag |= ME_HIDE;
+
+ mvertindex->bweight= (char)(255.0*eve->bweight);
+
+ eve= eve->next;
+ i++;
+ }
+
+ /* the faces , taken from lead_editMesh*/
+ i = 0;
+
+ efa = em->faces.first;
+ while(efa) {
+ mfaceindex = &((MFace *) mface)[i];
+
+ mfaceindex->v1= (unsigned int) efa->v1->tmp.l;
+ mfaceindex->v2= (unsigned int) efa->v2->tmp.l;
+ mfaceindex->v3= (unsigned int) efa->v3->tmp.l;
+ if (efa->v4) mfaceindex->v4 = (unsigned int) efa->v4->tmp.l;
+
+ mfaceindex->mat_nr= efa->mat_nr;
+ mfaceindex->flag= efa->flag;
+
+ i++;
+ efa= efa->next;
+ }
+ //mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
+}
+
/* makes Mesh out of editmesh */
void load_editMesh(Scene *scene, Object *ob)
{
@@ -1307,6 +1732,399 @@
mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
}
+/* makes Mesh out of editmesh */
+void load_editMesh_external(Scene *scene, Object *ob, EditMesh *em)
+{
+ Mesh *me= ob->data;
+ MVert *mvert, *oldverts;
+ MEdge *medge;
+ MFace *mface;
+ MSelect *mselect;
+ //EditMesh *em= me->edit_mesh;
+ EditVert *eve;
+ EditFace *efa, *efa_act;
+ EditEdge *eed;
+ EditSelection *ese;
+ float *fp, *newkey, *oldkey, nor[3];
+ int i, a, ototvert;
+
+ /* this one also tests of edges are not in faces: */
+ /* eed->f2==0: not in face, f2==1: draw it */
+ /* eed->f1 : flag for dynaface (cylindertest, old engine) */
+ /* eve->f1 : flag for dynaface (sphere test, old engine) */
+ /* eve->f2 : being used in vertexnormals */
+ edge_drawflags(me, em);
+
+ EM_stats_update(em);
+
+ /* new Vertex block */
+ if(em->totvert==0) mvert= NULL;
+ else mvert= MEM_callocN(em->totvert*sizeof(MVert), "loadeditMesh vert");
+
+ /* new Edge block */
+ if(em->totedge==0) medge= NULL;
+ else medge= MEM_callocN(em->totedge*sizeof(MEdge), "loadeditMesh edge");
+
+ /* new Face block */
+ if(em->totface==0) mface= NULL;
+ else mface= MEM_callocN(em->totface*sizeof(MFace), "loadeditMesh face");
+
+ /* lets save the old verts just in case we are actually working on
+ * a key ... we now do processing of the keys at the end */
+ oldverts= me->mvert;
+ ototvert= me->totvert;
+
+ /* don't free this yet */
+ CustomData_set_layer(&me->vdata, CD_MVERT, NULL);
+
+ /* free custom data */
+ CustomData_free(&me->vdata, me->totvert);
+ CustomData_free(&me->edata, me->totedge);
+ CustomData_free(&me->fdata, me->totface);
+
+ /* add new custom data */
+ me->totvert= em->totvert;
+ me->totedge= em->totedge;
+ me->totface= em->totface;
+
+ CustomData_copy(&em->vdata, &me->vdata, CD_MASK_MESH, CD_CALLOC,
me->totvert);
+ CustomData_copy(&em->edata, &me->edata, CD_MASK_MESH, CD_CALLOC,
me->totedge);
+ CustomData_copy(&em->fdata, &me->fdata, CD_MASK_MESH, CD_CALLOC,
me->totface);
+
+ CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert);
+ CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge);
+ CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, mface, me->totface);
+ mesh_update_customdata_pointers(me);
+
+ /* the vertices, use ->tmp.l as counter */
+ eve= em->verts.first;
+ a= 0;
+
+ while(eve) {
+ VECCOPY(mvert->co, eve->co);
+
+ mvert->mat_nr= 32767; /* what was this for, halos? */
+
+ /* vertex normal */
+ VECCOPY(nor, eve->no);
+ mul_v3_fl(nor, 32767.0);
+ VECCOPY(mvert->no, nor);
+
+ /* note: it used to remove me->dvert when it was not in use, cancelled
+ that... annoying when you have a fresh vgroup */
+ CustomData_from_em_block(&em->vdata, &me->vdata, eve->data, a);
+
+ eve->tmp.l = a++; /* counter */
+
+ mvert->flag= 0;
+ mvert->flag |= (eve->f & SELECT);
+ if (eve->h) mvert->flag |= ME_HIDE;
+
+ mvert->bweight= (char)(255.0*eve->bweight);
+
+ eve= eve->next;
+ mvert++;
+ }
+
+ /* the edges */
+ a= 0;
+ eed= em->edges.first;
+ while(eed) {
+ medge->v1= (unsigned int) eed->v1->tmp.l;
+ medge->v2= (unsigned int) eed->v2->tmp.l;
+
+ medge->flag= (eed->f & SELECT) | ME_EDGERENDER;
+ if(eed->f2<2) medge->flag |= ME_EDGEDRAW;
+ if(eed->f2==0) medge->flag |= ME_LOOSEEDGE;
+ if(eed->sharp) medge->flag |= ME_SHARP;
+ if(eed->seam) medge->flag |= ME_SEAM;
+ if(eed->h & EM_FGON) medge->flag |= ME_FGON; // different defines yes
+ if(eed->h & 1) medge->flag |= ME_HIDE;
+
+ medge->crease= (char)(255.0*eed->crease);
+ medge->bweight= (char)(255.0*eed->bweight);
+ CustomData_from_em_block(&em->edata, &me->edata, eed->data, a);
+
+ eed->tmp.l = a++;
+
+ medge++;
+ eed= eed->next;
+ }
+
+ /* the faces */
+ a = 0;
+ efa= em->faces.first;
+ efa_act= EM_get_actFace(em, 0);
+ i = 0;
+ me->act_face = -1;
+ while(efa) {
+ mface= &((MFace *) me->mface)[i];
+
+ mface->v1= (unsigned int) efa->v1->tmp.l;
+ mface->v2= (unsigned int) efa->v2->tmp.l;
+ mface->v3= (unsigned int) efa->v3->tmp.l;
+ if (efa->v4) mface->v4 = (unsigned int) efa->v4->tmp.l;
+
+ mface->mat_nr= efa->mat_nr;
+
+ mface->flag= efa->flag;
+ /* bit 0 of flag is already taken for smooth... */
+
+ if(efa->h) {
+ mface->flag |= ME_HIDE;
+ mface->flag &= ~ME_FACE_SEL;
+ } else {
+ if(efa->f & 1) mface->flag |= ME_FACE_SEL;
+ else mface->flag &= ~ME_FACE_SEL;
+ }
+
+ /* mat_nr in vertex */
+ if(me->totcol>1) {
+ mvert= me->mvert+mface->v1;
+ if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
+ mvert= me->mvert+mface->v2;
+ if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
+ mvert= me->mvert+mface->v3;
+ if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
+ if(mface->v4) {
+ mvert= me->mvert+mface->v4;
+ if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
+ }
+ }
+
+ /* watch: efa->e1->f2==0 means loose edge */
+
+ if(efa->e1->f2==1) {
+ efa->e1->f2= 2;
+ }
+ if(efa->e2->f2==1) {
+ efa->e2->f2= 2;
+ }
+ if(efa->e3->f2==1) {
+ efa->e3->f2= 2;
+ }
+ if(efa->e4 && efa->e4->f2==1) {
+ efa->e4->f2= 2;
+ }
+
+ CustomData_from_em_block(&em->fdata, &me->fdata, efa->data, i);
+
+ /* no index '0' at location 3 or 4 */
+ test_index_face(mface, &me->fdata, i, efa->v4?4:3);
+
+ if (efa_act == efa)
+ me->act_face = a;
+
+ efa->tmp.l = a++;
+ i++;
+ efa= efa->next;
+ }
+
+ /* patch hook indices and vertex parents */
+ {
+ Object *ob;
+ ModifierData *md;
+ EditVert **vertMap = NULL;
+ int i,j;
+
+ for (ob=G.main->object.first; ob; ob=ob->id.next) {
+ if (ob->parent==ob && ELEM(ob->partype, PARVERT1,PARVERT3)) {
+
+ /* duplicate code from below, make it function later...? */
+ if (!vertMap) {
+ vertMap = MEM_callocN(sizeof(*vertMap)*ototvert, "vertMap");
+
+ for (eve=em->verts.first; eve; eve=eve->next) {
+ if (eve->keyindex!=-1)
+ vertMap[eve->keyindex] = eve;
+ }
+ }
+ if(ob->par1 < ototvert) {
+ eve = vertMap[ob->par1];
+ if(eve) ob->par1= eve->tmp.l;
+ }
+ if(ob->par2 < ototvert) {
+ eve = vertMap[ob->par2];
+ if(eve) ob->par2= eve->tmp.l;
+ }
+ if(ob->par3 < ototvert) {
+ eve = vertMap[ob->par3];
+ if(eve) ob->par3= eve->tmp.l;
+ }
+
+ }
+ if (ob->data==me) {
+ for (md=ob->modifiers.first; md; md=md->next) {
+ if (md->type==eModifierType_Hook) {
+ HookModifierData *hmd = (HookModifierData*) md;
+
+ if (!vertMap) {
+ vertMap = MEM_callocN(sizeof(*vertMap)*ototvert, "vertMap");
+
+ for (eve=em->verts.first; eve; eve=eve->next) {
+ if (eve->keyindex!=-1)
+ vertMap[eve->keyindex] = eve;
+ }
+ }
+
+ for (i=j=0; i<hmd->totindex; i++) {
+ if(hmd->indexar[i] < ototvert) {
+ eve = vertMap[hmd->indexar[i]];
+
+ if (eve) {
+ hmd->indexar[j++] = eve->tmp.l;
+ }
+ }
+ else j++;
+ }
+
+ hmd->totindex = j;
+ }
+ }
+ }
+ }
+
+ if (vertMap) MEM_freeN(vertMap);
+ }
+
+ /* are there keys? */
+ if(me->key) {
+ KeyBlock *currkey;
+ KeyBlock *actkey= BLI_findlink(&me->key->block, em->shapenr-1);
+
+ float (*ofs)[3] = NULL;
+
+ /* editing the base key should update others */
+ if(me->key->type==KEY_RELATIVE && oldverts) {
+ int act_is_basis = 0;
+ /* find if this key is a basis for any others */
+ for(currkey = me->key->block.first; currkey; currkey= currkey->next) {
+ if(em->shapenr-1 == currkey->relative) {
+ act_is_basis = 1;
+ break;
+ }
+ }
+
+ if(act_is_basis) { /* active key is a base */
+ i=0;
+ ofs= MEM_callocN(sizeof(float) * 3 * em->totvert, "currkey->data");
+ eve= em->verts.first;
+ mvert = me->mvert;
+ while(eve) {
+ VECSUB(ofs[i], mvert->co, oldverts[eve->keyindex].co);
+ eve= eve->next;
+ i++;
+ mvert++;
+ }
+ }
+ }
+
+
+ /* Lets reorder the key data so that things line up roughly
+ * with the way things were before editmode */
+ currkey = me->key->block.first;
+ while(currkey) {
+ int apply_offset = (ofs && (currkey != actkey) && (em->shapenr-1 ==
currkey->relative));
+
+ fp= newkey= MEM_callocN(me->key->elemsize*em->totvert, "currkey->data");
+ oldkey = currkey->data;
+
+ eve= em->verts.first;
+
+ i = 0;
+ mvert = me->mvert;
+ while(eve) {
+ if (eve->keyindex >= 0 && eve->keyindex < currkey->totelem) { //
valid old vertex
+ if(currkey == actkey) {
+ if(actkey == me->key->refkey) {
+ VECCOPY(fp, mvert->co);
+ }
+ else {
+ VECCOPY(fp, mvert->co);
+ if(oldverts) {
+ VECCOPY(mvert->co, oldverts[eve->keyindex].co);
+ }
+ }
+ }
+ else {
+ if(oldkey) {
+ VECCOPY(fp, oldkey + 3 * eve->keyindex);
+ }
+ }
+ }
+ else {
+ VECCOPY(fp, mvert->co);
+ }
+
+ /* propagate edited basis offsets to other shapes */
+ if(apply_offset) {
+ VECADD(fp, fp, ofs[i]);
+ }
+
+ fp+= 3;
+ ++i;
+ ++mvert;
+ eve= eve->next;
+ }
+ currkey->totelem= em->totvert;
+ if(currkey->data) MEM_freeN(currkey->data);
+ currkey->data = newkey;
+
+ currkey= currkey->next;
+ }
+
+ if(ofs) MEM_freeN(ofs);
+ }
+
+ if(oldverts) MEM_freeN(oldverts);
+
+ i = 0;
+ for(ese=em->selected.first; ese; ese=ese->next) i++;
+ me->totselect = i;
+ if(i==0) mselect= NULL;
+ else mselect= MEM_callocN(i*sizeof(MSelect), "loadeditMesh selections");
+
+ if(me->mselect) MEM_freeN(me->mselect);
+ me->mselect= mselect;
+
+ for(ese=em->selected.first; ese; ese=ese->next){
+ mselect->type = ese->type;
+ if(ese->type == EDITVERT) mselect->index = ((EditVert*)ese->data)->tmp.l;
+ else if(ese->type == EDITEDGE) mselect->index =
((EditEdge*)ese->data)->tmp.l;
+ else if(ese->type == EDITFACE) mselect->index =
((EditFace*)ese->data)->tmp.l;
+ mselect++;
+ }
+
+ /* to be sure: clear ->tmp.l pointers */
+ eve= em->verts.first;
+ while(eve) {
+ eve->tmp.l = 0;
+ eve= eve->next;
+ }
+
+ eed= em->edges.first;
+ while(eed) {
+ eed->tmp.l = 0;
+ eed= eed->next;
+ }
+
+ efa= em->faces.first;
+ while(efa) {
+ efa->tmp.l = 0;
+ efa= efa->next;
+ }
+
+ /* remake softbody of all users */
+ if(me->id.us>1) {
+ Base *base;
+ for(base= scene->base.first; base; base= base->next)
+ if(base->object->data==me)
+ base->object->recalc |= OB_RECALC_DATA;
+ }
+
+ mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
+}
+
void remake_editMesh(Scene *scene, Object *ob)
{
make_editMesh(scene, ob);
Index: source/blender/editors/mesh/editmesh_add.c
===================================================================
--- source/blender/editors/mesh/editmesh_add.c (revision 32564)
+++ source/blender/editors/mesh/editmesh_add.c (working copy)
@@ -824,7 +824,124 @@
recalc_editnormals(em);
}
}
+
+void addedgeface_mesh_uclay(EditMesh *em)
+{
+ EditVert *eve, *neweve[4];
+ EditEdge *eed;
+ EditFace *efa;
+ short amount=0;
+ /* how many selected ? */
+ if(em->selectmode & SCE_SELECT_EDGE) {
+ /* in edge mode finding selected vertices means flushing down edge
codes... */
+ /* can't make face with only edge selection info... */
+ EM_selectmode_set(em);
+ }
+
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ if(eve->f & SELECT) {
+ amount++;
+ if(amount>4) break;
+ neweve[amount-1]= eve;
+ }
+ }
+
+ if(amount==2) {
+ eed= addedgelist(em, neweve[0], neweve[1], NULL);
+ EM_select_edge(eed, 1);
+
+ // XXX DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+ return;
+ }
+ else if(amount > 4) {
+ addfaces_from_edgenet(em);
+ return;
+ }
+ else if(amount<2) {
+ // BKE_report(op->reports, RPT_ERROR, "More vertices are needed to make
an edge/face");
+ return;
+ }
+
+ efa= NULL; // check later
+
+ if(amount==3) {
+
+ if(exist_face_overlaps(em, neweve[0], neweve[1], neweve[2], NULL)==0) {
+ efa= addfacelist(em, neweve[0], neweve[1], neweve[2], 0, NULL, NULL);
+ EM_select_face(efa, 1);
+ }
+ // else BKE_report(op->reports, RPT_ERROR, "The selected vertices
already form a face");
+ }
+ else if(amount==4) {
+ /* this test survives when theres 2 triangles */
+ if(exist_face(em, neweve[0], neweve[1], neweve[2], neweve[3])==0) {
+ int tria= 0;
+
+ /* remove trias if they exist, 4 cases.... */
+ if(exist_face(em, neweve[0], neweve[1], neweve[2], NULL)) tria++;
+ if(exist_face(em, neweve[0], neweve[1], neweve[3], NULL)) tria++;
+ if(exist_face(em, neweve[0], neweve[2], neweve[3], NULL)) tria++;
+ if(exist_face(em, neweve[1], neweve[2], neweve[3], NULL)) tria++;
+
+ if(tria==2) join_triangles(em);
+ else if(exist_face_overlaps(em, neweve[0], neweve[1], neweve[2],
neweve[3])==0) {
+ /* If there are 4 Verts, But more selected edges, we need to call
addfaces_from_edgenet */
+ EditEdge *eedcheck;
+ int count;
+ count = 0;
+ for(eedcheck= em->edges.first; eedcheck; eedcheck= eedcheck->next) {
+ if(eedcheck->f & SELECT) {
+ count++;
+ }
+ }
+
+ if(count++ > 4){
+ addfaces_from_edgenet(em);
+ return;
+ } else {
+ /* if 4 edges exist, we just create the face, convex or not */
+ efa= addface_from_edges(em);
+ if(efa==NULL) {
+
+ /* the order of vertices can be anything, 6 cases to check */
+ if( convex(neweve[0]->co, neweve[1]->co, neweve[2]->co,
neweve[3]->co) ) {
+ efa= addfacelist(em, neweve[0], neweve[1], neweve[2], neweve[3],
NULL, NULL);
+ }
+ else if( convex(neweve[0]->co, neweve[2]->co, neweve[3]->co,
neweve[1]->co) ) {
+ efa= addfacelist(em, neweve[0], neweve[2], neweve[3], neweve[1],
NULL, NULL);
+ }
+ else if( convex(neweve[0]->co, neweve[2]->co, neweve[1]->co,
neweve[3]->co) ) {
+ efa= addfacelist(em, neweve[0], neweve[2], neweve[1], neweve[3],
NULL, NULL);
+ }
+ else if( convex(neweve[0]->co, neweve[1]->co, neweve[3]->co,
neweve[2]->co) ) {
+ efa= addfacelist(em, neweve[0], neweve[1], neweve[3], neweve[2],
NULL, NULL);
+ }
+ else if( convex(neweve[0]->co, neweve[3]->co, neweve[2]->co,
neweve[1]->co) ) {
+ efa= addfacelist(em, neweve[0], neweve[3], neweve[2], neweve[1],
NULL, NULL);
+ }
+ else if( convex(neweve[0]->co, neweve[3]->co, neweve[1]->co,
neweve[2]->co) ) {
+ efa= addfacelist(em, neweve[0], neweve[3], neweve[1], neweve[2],
NULL, NULL);
+ }
+ // else BKE_report(op->reports, RPT_ERROR, "cannot find nice quad
from concave set of vertices");
+
+ }
+ }
+ }
+ // else BKE_report(op->reports, RPT_ERROR, "The selected vertices
already form a face");
+ }
+ // else BKE_report(op->reports, RPT_ERROR, "The selected vertices
already form a face");
+ }
+
+ if(efa) {
+ EM_select_face(efa, 1);
+
+ fix_new_face(em, efa);
+
+ recalc_editnormals(em);
+ }
+ }
+
static int addedgeface_mesh_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
Index: source/blender/editors/mesh/editmesh_mods.c
===================================================================
--- source/blender/editors/mesh/editmesh_mods.c (revision 32564)
+++ source/blender/editors/mesh/editmesh_mods.c (working copy)
@@ -4425,6 +4425,144 @@
RNA_def_boolean(ot->srna, "zaxis", 1, "Z-Axis", "Smooth along the Z
axis.");
}
+int smooth_vertex_editmesh(Object *obedit, EditMesh *em) //Mio
+{
+ EditVert *eve, *eve_mir = NULL;
+ EditEdge *eed;
+ float *adror, *adr, fac;
+ float fvec[3];
+ int teller=0;
+ ModifierData *md;
+ int index;
+
+ /* count */
+ eve= em->verts.first;
+ while(eve) {
+ teller++; //if(eve->f & SELECT)
+ eve= eve->next;
+ }
+ if(teller==0) {
+ BKE_mesh_end_editmesh(obedit->data, em);
+ return OPERATOR_CANCELLED;
+ }
+
+ adr=adror= (float *)MEM_callocN(3*sizeof(float *)*teller, "vertsmooth");
+ eve= em->verts.first;
+ while(eve) {
+ { //if(eve->f & SELECT)
+ eve->tmp.p = (void*)adr;
+ eve->f1= 0;
+ eve->f2= 0;
+ adr+= 3;
+ }
+ eve= eve->next;
+ }
+
+ /* if there is a mirror modifier with clipping, flag the verts that
+ * are within tolerance of the plane(s) of reflection
+ */
+ for(md=obedit->modifiers.first; md; md=md->next) {
+ if(md->type==eModifierType_Mirror) {
+ MirrorModifierData *mmd = (MirrorModifierData*) md;
+
+ if(mmd->flag & MOD_MIR_CLIPPING) {
+ for (eve= em->verts.first; eve; eve= eve->next) {
+ { //if(eve->f & SELECT)
+
+ switch(mmd->axis){
+ case 0:
+ if (fabs(eve->co[0]) < mmd->tolerance)
+ eve->f2 |= 1;
+ break;
+ case 1:
+ if (fabs(eve->co[1]) < mmd->tolerance)
+ eve->f2 |= 2;
+ break;
+ case 2:
+ if (fabs(eve->co[2]) < mmd->tolerance)
+ eve->f2 |= 4;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ eed= em->edges.first;
+ while(eed) { //count selected times
+ { //if( (eed->v1->f & SELECT) || (eed->v2->f & SELECT) )
+ fvec[0]= (eed->v1->co[0]+eed->v2->co[0])/2.0;
+ fvec[1]= (eed->v1->co[1]+eed->v2->co[1])/2.0;
+ fvec[2]= (eed->v1->co[2]+eed->v2->co[2])/2.0;
+
+ if( eed->v1->f1<255) { //(eed->v1->f & SELECT) &&
+ eed->v1->f1++;
+ add_v3_v3(eed->v1->tmp.p, fvec);
+ }
+ if( eed->v2->f1<255) { //(eed->v2->f & SELECT) &&
+ eed->v2->f1++;
+ add_v3_v3(eed->v2->tmp.p, fvec);
+ }
+ }
+ eed= eed->next;
+ }
+
+ index= 0;
+ eve= em->verts.first;
+ while(eve) {
+ { //if(eve->f & SELECT)
+ if(eve->f1) {
+
+
+ if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) {
+ eve_mir= editmesh_get_x_mirror_vert(obedit, em, eve, eve->co, index);
+ }
+
+ adr = eve->tmp.p;
+ fac= 0.5/(float)eve->f1;
+
+ eve->co[0]= 0.5*eve->co[0]+fac*adr[0];
+ eve->co[1]= 0.5*eve->co[1]+fac*adr[1];
+ eve->co[2]= 0.5*eve->co[2]+fac*adr[2];
+
+ /* clip if needed by mirror modifier */
+ if (eve->f2) {
+ if (eve->f2 & 1) {
+ eve->co[0]= 0.0f;
+ }
+ if (eve->f2 & 2) {
+ eve->co[1]= 0.0f;
+ }
+ if (eve->f2 & 4) {
+ eve->co[2]= 0.0f;
+ }
+ }
+
+ if (eve_mir) {
+ eve_mir->co[0]=-eve->co[0];
+ eve_mir->co[1]= eve->co[1];
+ eve_mir->co[2]= eve->co[2];
+ }
+
+ }
+ eve->tmp.p= NULL;
+ }
+ index++;
+ eve= eve->next;
+ }
+ MEM_freeN(adror);
+
+ recalc_editnormals(em);
+
+ BKE_mesh_end_editmesh(obedit->data, em);
+
+ //DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+ //WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+
+ return OPERATOR_FINISHED;
+}
+
void vertexnoise(Object *obedit, EditMesh *em)
{
Material *ma;
@@ -4612,3 +4750,4 @@
RNA_def_int(ot->srna, "nth", 2, 2, 100, "Nth Selection", "", 1, INT_MAX);
}
+
Index: source/blender/editors/mesh/editmesh_tools.c
===================================================================
--- source/blender/editors/mesh/editmesh_tools.c (revision 32564)
+++ source/blender/editors/mesh/editmesh_tools.c (working copy)
@@ -171,6 +171,44 @@
}
+void convert_to_triface_all(EditMesh *em, int direction)
+{
+ EditFace *efa, *efan, *next;
+ float fac;
+
+ efa= em->faces.last;
+ while(efa) {
+ next= efa->prev;
+ if(efa->v4) {
+ //if(efa->f & SELECT) {
+ /* choose shortest diagonal for split */
+ fac= len_v3v3(efa->v1->co, efa->v3->co) - len_v3v3(efa->v2->co,
efa->v4->co);
+ /* this makes sure exact squares get split different in both cases */
+ if( (direction==0 && fac<FLT_EPSILON) || (direction && fac>0.0f) ) {
+ efan= EM_face_from_faces(em, efa, NULL, 0, 1, 2, -1);
+ if(efa->f & SELECT) EM_select_face(efan, 1);
+ efan= EM_face_from_faces(em, efa, NULL, 0, 2, 3, -1);
+ if(efa->f & SELECT) EM_select_face(efan, 1);
+ }
+ else {
+ efan= EM_face_from_faces(em, efa, NULL, 0, 1, 3, -1);
+ if(efa->f & SELECT) EM_select_face(efan, 1);
+ efan= EM_face_from_faces(em, efa, NULL, 1, 2, 3, -1);
+ if(efa->f & SELECT) EM_select_face(efan, 1);
+ }
+
+ BLI_remlink(&em->faces, efa);
+ free_editface(em, efa);
+ //}
+ }
+ efa= next;
+ }
+
+ EM_fgon_flags(em); // redo flags and indices for fgons
+
+
+}
+
int removedoublesflag(EditMesh *em, short flag, short automerge, float
limit) /* return amount */
{
/*
@@ -2967,6 +3005,165 @@
recalc_editnormals(em);
}
+//------------
+void esubdivideflag_local(Object *obedit, EditMesh *em, int flag, float
smooth, float fractal, int beauty, int numcuts, int corner_pattern, int
seltype)
+{
+ EditFace *ef;
+ EditEdge *eed, *cedge;
+ EditVert **templist;
+ struct GHash *gh;
+ int i,edgecount, facetype;
+ ModifierData *md= obedit->modifiers.first;
+ int ctrl= 0; // XXX
+
+ // We store an array of verts for each edge that is subdivided,
+ // we put this array as a value in a ghash which is keyed by the EditEdge*
+
+ gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp,
"subdivideedgenum gh");
+ //Flush vertex flags upward to the edges
+ // So for each edge, if it is selected, we allocate an array of size cuts+2
+ // so we can have a place for the v1, the new verts and v2
+ for(eed = em->edges.first;eed;eed = eed->next) {
+ eed->f2 = 0;
+ if(eed->f & flag) {
+ eed->f2 |= EDGEOLD;
+
+ templist = MEM_mallocN(sizeof(EditVert*)*(numcuts+2),"vertlist");
+ templist[0] = eed->v1;
+ for(i=0;i<numcuts;i++) {
+ // This function creates the new vert and returns it back
+ // to the array
+ templist[i+1] = subdivideedgenum(em, eed, i+1, numcuts, smooth,
fractal, beauty);
+ //while we are here, we can copy edge info from the original edge
+ cedge = addedgelist(em, templist[i],templist[i+1],eed);
+ // Also set the edge f2 to EDGENEW so that we can use this info later
+ templist[i+1]->f1 = SELECT; //set for uclay smooth
+ cedge->f2 = EDGENEW;
+ }
+ templist[i+1] = eed->v2;
+ //Do the last edge too
+ cedge = addedgelist(em, templist[i],templist[i+1],eed);
+ cedge->f2 = EDGENEW;
+ // Now that the edge is subdivided, we can put its verts in the ghash
+ BLI_ghash_insert(gh, eed, templist);
+ }
+ }
+
+ /*/ Now for each face in the mesh we need to figure out How many edges
were cut
+ // and which filling method to use for that face */
+ for(ef = em->faces.first;ef;ef = ef->next) {
+ edgecount = 0;
+ facetype = 3;
+ if(ef->e1->f & flag) {edgecount++;}
+ if(ef->e2->f & flag) {edgecount++;}
+ if(ef->e3->f & flag) {edgecount++;}
+ if(ef->v4) {
+ facetype = 4;
+ if(ef->e4->f & flag) {edgecount++;}
+ }
+ if(facetype == 4) {
+ switch(edgecount) {
+ case 0:
+ break;
+
+ case 1:
+ ef->f1 = SELECT;
+ fill_quad_single(em, ef, gh, numcuts, seltype);
+ break;
+ case 2: ef->f1 = SELECT;
+ // if there are 2, we check if edge 1 and 3 are either both on or
off that way
+ // we can tell if the selected pair is Adjacent or Opposite of each
other
+ if((ef->e1->f & flag && ef->e3->f & flag) ||
+ (ef->e2->f & flag && ef->e4->f & flag)) {
+ fill_quad_double_op(em, ef, gh, numcuts);
+ }else{
+ switch(corner_pattern) {
+ case 0: fill_quad_double_adj_path(em, ef, gh, numcuts); break;
+ case 1: fill_quad_double_adj_inner(em, ef, gh, numcuts); break;
+ case 2: fill_quad_double_adj_fan(em, ef, gh, numcuts); break;
+ }
+ }
+ break;
+ case 3: ef->f1 = SELECT;
+ fill_quad_triple(em, ef, gh, numcuts);
+ break;
+ case 4: ef->f1 = SELECT;
+ fill_quad_quadruple(em, ef, gh, numcuts, smooth, fractal, beauty);
+ break;
+ }
+ } else {
+ switch(edgecount) {
+ case 0: break;
+ case 1: ef->f1 = SELECT;
+ fill_tri_single(em, ef, gh, numcuts, seltype);
+ break;
+ case 2: ef->f1 = SELECT;
+ fill_tri_double(em, ef, gh, numcuts);
+ break;
+ case 3: ef->f1 = SELECT;
+ fill_tri_triple(em, ef, gh, numcuts, smooth, fractal, beauty);
+ break;
+ }
+ }
+ }
+
+ // Delete Old Edges and Faces
+ for(eed = em->edges.first;eed;eed = eed->next) {
+ if(BLI_ghash_haskey(gh,eed)) {
+ eed->f1 = SELECT;
+ } else {
+ eed->f1 = 0;
+ }
+ }
+ free_tagged_edges_faces(em, em->edges.first, em->faces.first);
+
+ if(seltype == SUBDIV_SELECT_ORIG && !ctrl) {
+ // bugfix: vertex could get flagged as "not-selected"
+ // solution: clear flags before, not at the same time as setting SELECT
flag -dg
+
+ for(eed = em->edges.first;eed;eed = eed->next) {
+ if(!(eed->f2 & EDGENEW || eed->f2 & EDGEOLD)) {
+ eed->f &= !flag;
+ EM_select_edge(eed,0);
+ }
+ }
+ for(eed = em->edges.first;eed;eed = eed->next) {
+ if(eed->f2 & EDGENEW || eed->f2 & EDGEOLD) {
+ eed->f |= flag;
+ EM_select_edge(eed,1);
+ }
+ }
+ } else if ((seltype == SUBDIV_SELECT_INNER || seltype ==
SUBDIV_SELECT_INNER_SEL)|| ctrl) {
+ for(eed = em->edges.first;eed;eed = eed->next) {
+ if(eed->f2 & EDGEINNER) {
+ eed->f |= flag;
+ EM_select_edge(eed,1);
+ if(eed->v1->f & EDGEINNER) eed->v1->f |= SELECT;
+ if(eed->v2->f & EDGEINNER) eed->v2->f |= SELECT;
+ }else{
+ eed->f &= !flag;
+ EM_select_edge(eed,0);
+ }
+ }
+ } else if(seltype == SUBDIV_SELECT_LOOPCUT){
+ for(eed = em->edges.first;eed;eed = eed->next) {
+ if(eed->f2 & DOUBLEOPFILL){
+ eed->f |= flag;
+ EM_select_edge(eed,1);
+ }else{
+ eed->f &= !flag;
+ EM_select_edge(eed,0);
+ }
+ }
+ }
+
+ // Free the ghash and call MEM_freeN on all the value entries to return
+ // that memory
+ BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN);
+
+ recalc_editnormals(em);
+}
+
static int count_selected_edges(EditEdge *ed)
{
int totedge = 0;
@@ -3123,7 +3320,7 @@
}
/** remove and free list of tagged edges and faces */
-static void free_tagged_edges_faces(EditMesh *em, EditEdge *eed, EditFace
*efa)
+void free_tagged_edges_faces(EditMesh *em, EditEdge *eed, EditFace *efa)
{
EditEdge *nexted;
EditFace *nextvl;
@@ -6778,7 +6975,7 @@
/* note; the EM_selectmode_set() calls here illustrate how badly
constructed it all is... from before the
edge/face flags, with very mixed results.... */
-static void beautify_fill(EditMesh *em)
+void beautify_fill(EditMesh *em)
{
EditVert *v1, *v2, *v3, *v4;
EditEdge *eed, *nexted;
@@ -6942,7 +7139,7 @@
/* Got this from scanfill.c. You will need to juggle around the
* callbacks for the scanfill.c code a bit for this to work. */
-static void fill_mesh(EditMesh *em)
+void fill_mesh(EditMesh *em)
{
EditVert *eve,*v1;
EditEdge *eed,*e1,*nexted;
Index: source/blender/editors/mesh/mesh_intern.h
===================================================================
--- source/blender/editors/mesh/mesh_intern.h (revision 32564)
+++ source/blender/editors/mesh/mesh_intern.h (working copy)
@@ -32,39 +32,9 @@
#ifndef MESH_INTERN_H
#define MESH_INTERN_H
-struct bContext;
-struct wmOperatorType;
-struct wmOperator;
+extern EnumPropertyItem corner_type_items[];
-#define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float));
-
-/* ******************** editface.c */
-
-int edgetag_context_check(Scene *scene, EditEdge *eed);
-void edgetag_context_set(Scene *scene, EditEdge *eed, int val);
-int edgetag_shortest_path(Scene *scene, EditMesh *em, EditEdge *source,
EditEdge *target);
-
-/* ******************* editmesh.c */
-
-extern void free_editvert(EditMesh *em, EditVert *eve);
-extern void free_editedge(EditMesh *em, EditEdge *eed);
-extern void free_editface(EditMesh *em, EditFace *efa);
-void free_editMesh(EditMesh *em);
-
-extern void free_vertlist(EditMesh *em, ListBase *edve);
-extern void free_edgelist(EditMesh *em, ListBase *lb);
-extern void free_facelist(EditMesh *em, ListBase *lb);
-
-extern void remedge(EditMesh *em, EditEdge *eed);
-
-extern struct EditVert *addvertlist(EditMesh *em, float *vec, struct
EditVert *example);
-extern struct EditEdge *addedgelist(EditMesh *em, struct EditVert *v1,
struct EditVert *v2, struct EditEdge *example);
-extern struct EditFace *addfacelist(EditMesh *em, struct EditVert *v1,
struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct
EditFace *example, struct EditFace *exampleEdges);
-extern struct EditEdge *findedgelist(EditMesh *em, struct EditVert *v1,
struct EditVert *v2);
-
-void em_setup_viewcontext(struct bContext *C, ViewContext *vc);
-
void MESH_OT_separate(struct wmOperatorType *ot);
/* ******************* editmesh_add.c */
@@ -85,61 +55,7 @@
void MESH_OT_fgon_make(struct wmOperatorType *ot);
void MESH_OT_fgon_clear(struct wmOperatorType *ot);
-/* ******************* editmesh_lib.c */
-void EM_stats_update(EditMesh *em);
-extern void EM_fgon_flags(EditMesh *em);
-extern void EM_hide_reset(EditMesh *em);
-
-extern int faceselectedOR(EditFace *efa, int flag);
-extern int faceselectedAND(EditFace *efa, int flag);
-
-void EM_remove_selection(EditMesh *em, void *data, int type);
-void EM_clear_flag_all(EditMesh *em, int flag);
-void EM_set_flag_all(EditMesh *em, int flag);
-void EM_set_flag_all_selectmode(EditMesh *em, int flag);
-
-void EM_data_interp_from_verts(EditMesh *em, EditVert *v1, EditVert *v2,
EditVert *eve, float fac);
-void EM_data_interp_from_faces(EditMesh *em, EditFace *efa1, EditFace
*efa2, EditFace *efan, int i1, int i2, int i3, int i4);
-
-int EM_nvertices_selected(EditMesh *em);
-int EM_nedges_selected(EditMesh *em);
-int EM_nfaces_selected(EditMesh *em);
-
-float EM_face_perimeter(EditFace *efa);
-
-void EM_store_selection(EditMesh *em, void *data, int type);
-
-extern EditFace *exist_face(EditMesh *em, EditVert *v1, EditVert *v2,
EditVert *v3, EditVert *v4);
-extern void flipface(EditMesh *em, EditFace *efa); // flips for normal
direction
-extern int compareface(EditFace *vl1, EditFace *vl2);
-
-/* flag for selection bits, *nor will be filled with normal for extrusion
constraint */
-/* return value defines if such normal was set */
-extern short extrudeflag_face_indiv(EditMesh *em, short flag, float *nor);
-extern short extrudeflag_verts_indiv(EditMesh *em, short flag, float *nor);
-extern short extrudeflag_edges_indiv(EditMesh *em, short flag, float *nor);
-extern short extrudeflag_vert(Object *obedit, EditMesh *em, short flag,
float *nor, int all);
-extern short extrudeflag(Object *obedit, EditMesh *em, short flag, float
*nor, int all);
-
-extern void adduplicateflag(EditMesh *em, int flag);
-extern void delfaceflag(EditMesh *em, int flag);
-
-extern void rotateflag(EditMesh *em, short flag, float *cent, float
rotmat[][3]);
-extern void translateflag(EditMesh *em, short flag, float *vec);
-
-extern int convex(float *v1, float *v2, float *v3, float *v4);
-
-extern struct EditFace *EM_face_from_faces(EditMesh *em, struct EditFace
*efa1,
- struct EditFace *efa2, int i1, int i2, int i3, int i4);
-
-extern int EM_view3d_poll(struct bContext *C);
-
-/* ******************* editmesh_loop.c */
-
-#define LOOP_SELECT 1
-#define LOOP_CUT 2
-
void MESH_OT_knife_cut(struct wmOperatorType *ot);
/* ******************* editmesh_mods.c */
@@ -169,46 +85,9 @@
void MESH_OT_solidify(struct wmOperatorType *ot);
void MESH_OT_select_nth(struct wmOperatorType *ot);
+int EdgeSlide(struct EditMesh *em, struct wmOperator *op, short
immediate, float imperc);
+extern int convex(float *v1, float *v2, float *v3, float *v4);
-extern EditEdge *findnearestedge(ViewContext *vc, int *dist);
-extern void EM_automerge(Scene *scene, Object *obedit, int update);
-void editmesh_select_by_material(EditMesh *em, int index);
-void EM_recalc_normal_direction(EditMesh *em, int inside, int select); /*
makes faces righthand turning */
-void EM_select_more(EditMesh *em);
-void selectconnected_mesh_all(EditMesh *em);
-void faceloop_select(EditMesh *em, EditEdge *startedge, int select);
-
-/**
- * findnearestvert
- *
- * dist (in/out): minimal distance to the nearest and at the end, actual
distance
- * sel: selection bias
- * if SELECT, selected vertice are given a 5 pixel bias to make them
farter than unselect verts
- * if 0, unselected vertice are given the bias
- * strict: if 1, the vertice corresponding to the sel parameter are
ignored and not just biased
- */
-extern EditVert *findnearestvert(ViewContext *vc, int *dist, short sel,
short strict);
-
-
-/* ******************* editmesh_tools.c */
-
-#define SUBDIV_SELECT_ORIG 0
-#define SUBDIV_SELECT_INNER 1
-#define SUBDIV_SELECT_INNER_SEL 2
-#define SUBDIV_SELECT_LOOPCUT 3
-
-/* edge subdivide corner cut types */
-#define SUBDIV_CORNER_PATH 0
-#define SUBDIV_CORNER_INNERVERT 1
-#define SUBDIV_CORNER_FAN 2
-
-extern EnumPropertyItem corner_type_items[];
-
-void join_triangles(EditMesh *em);
-int removedoublesflag(EditMesh *em, short flag, short automerge, float
limit); /* return amount */
-void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth,
float fractal, int beautify, int numcuts, int corner_pattern, int
seltype);
-int EdgeSlide(EditMesh *em, struct wmOperator *op, short immediate, float
imperc);
-
void MESH_OT_merge(struct wmOperatorType *ot);
void MESH_OT_subdivide(struct wmOperatorType *ot);
void MESH_OT_remove_doubles(struct wmOperatorType *ot);
@@ -258,3 +137,4 @@
#endif // MESH_INTERN_H
+
Index: source/blender/editors/sculpt_paint/sculpt.c
===================================================================
--- source/blender/editors/sculpt_paint/sculpt.c (revision 32564)
+++ source/blender/editors/sculpt_paint/sculpt.c (working copy)
@@ -127,12 +127,38 @@
return NULL;
}
+/* Sculpt mode handles unlimited clay differently from regular meshes,
but only if
+ it's the last modifier on the stack and it is not on the first level */
+struct UClayModifierData *sculpt_uclay_active(Scene *scene, Object *ob)
+{
+ Mesh *me= (Mesh*)ob->data;
+ ModifierData *md, *nmd;
+
+ for(md= modifiers_getVirtualModifierList(ob); md; md= md->next) {
+ if(md->type == eModifierType_UClay) {
+ UClayModifierData *ucmd= (UClayModifierData*)md;
+
+ /* Check if any of the modifiers after multires are active
+ * if not it can use the multires struct */
+ for(nmd= md->next; nmd; nmd= nmd->next)
+ if(modifier_isEnabled(scene, nmd, eModifierMode_Realtime))
+ break;
+
+ if(!nmd )
+ return ucmd;
+ }
+ }
+
+ return NULL;
+}
+
+
/* Checks whether full update mode (slower) needs to be used to work with
modifiers */
int sculpt_modifiers_active(Scene *scene, Object *ob)
{
ModifierData *md;
MultiresModifierData *mmd= sculpt_multires_active(scene, ob);
-
+
/* check if there are any modifiers after what we are sculpting,
for a multires modifier with a deform modifier in front, we
do no need to recalculate the modifier stack. note that this
@@ -167,65 +193,8 @@
For descriptions of these settings, check the operator properties.
*/
-typedef struct StrokeCache {
- /* Invariants */
- float initial_radius;
- float scale[3];
- int flag;
- float clip_tolerance[3];
- float initial_mouse[2];
- /* Variants */
- float radius;
- float radius_squared;
- //float traced_location[3];
- float true_location[3];
- float location[3];
- float pen_flip;
- float invert;
- float pressure;
- float mouse[2];
- float bstrength;
- float tex_mouse[2];
-
- /* The rest is temporary storage that isn't saved as a property */
-
- int first_time; /* Beginning of stroke may do some things special */
-
- bglMats *mats;
-
- /* Clean this up! */
- ViewContext *vc;
- Brush *brush;
-
- float (*face_norms)[3]; /* Copy of the mesh faces' normals */
- float special_rotation; /* Texture rotation (radians) for anchored and
rake modes */
- int pixel_radius, previous_pixel_radius;
- float grab_delta[3], grab_delta_symmetry[3];
- float old_grab_location[3], orig_grab_location[3];
-
- int symmetry; /* Symmetry index between 0 and 7 bit combo 0 is Brush only;
- 1 is X mirror; 2 is Y mirror; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is
XYZ */
- int mirror_symmetry_pass; /* the symmetry pass we are currently on
between 0 and 7*/
- float true_view_normal[3];
- float view_normal[3];
- float last_area_normal[3];
- float last_center[3];
- int radial_symmetry_pass;
- float symm_rot_mat[4][4];
- float symm_rot_mat_inv[4][4];
- float last_rake[2]; /* Last location of updating rake rotation */
- int original;
-
- float vertex_rotation;
-
- char saved_active_brush_name[24];
- int alt_smooth;
-
- float plane_trim_squared;
-} StrokeCache;
-
/* ===== OPENGL =====
*
* Simple functions to get data from the GL
@@ -891,7 +860,7 @@
add_norm_if(ss->cache->view_normal, private_an, private_out_flip, fno);
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
else {
BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) {
@@ -907,7 +876,7 @@
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
#pragma omp critical
@@ -1039,11 +1008,10 @@
sculpt_clip(sd, ss, vd.co, val);
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss,
PBVHNode *node, float bstrength)
@@ -1195,7 +1163,9 @@
int n;
calc_sculpt_normal(sd, ss, area_normal, nodes, totnode);
+
+
/* offset with as much as possible factored in already */
mul_v3_v3fl(offset, area_normal, ss->cache->radius);
mul_v3_v3(offset, ss->cache->scale);
@@ -1218,13 +1188,12 @@
/* offset vertex */
float fade = tex_strength(ss, brush, vd.co,
test.dist)*frontface(brush, area_normal, vd.no, vd.fno);
- mul_v3_v3fl(proxy[vd.i], offset, fade);
-
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ mul_v3_v3fl(proxy[vd.i], offset, fade);
+
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
}
@@ -1283,11 +1252,10 @@
add_v3_v3v3(proxy[vd.i], val1, val2);
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
}
@@ -1315,11 +1283,10 @@
sub_v3_v3v3(val, test.location, vd.co);
mul_v3_v3fl(proxy[vd.i], val, fade);
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
}
@@ -1367,11 +1334,10 @@
mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
}
@@ -1407,11 +1373,10 @@
mul_v3_v3fl(proxy[vd.i], cono, fade);
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
}
@@ -1455,11 +1420,10 @@
mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
}
@@ -1502,11 +1466,10 @@
mul_v3_v3fl(proxy[vd.i], cono, fade);
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
}
@@ -1549,11 +1512,10 @@
sub_v3_v3(proxy[vd.i], origco[vd.i]);
mul_v3_fl(proxy[vd.i], fade);
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
}
@@ -1620,11 +1582,10 @@
sculpt_clip(sd, ss, vd.co, val);
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
}
@@ -1655,11 +1616,10 @@
mul_v3_fl(val, fade * ss->cache->radius);
mul_v3_v3v3(proxy[vd.i], val, ss->cache->scale);
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
}
@@ -1691,7 +1651,7 @@
private_count++;
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
else {
BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) {
@@ -1700,7 +1660,7 @@
private_count++;
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
#pragma omp critical
@@ -1760,7 +1720,7 @@
private_count++;
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
else {
BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) {
@@ -1781,7 +1741,7 @@
private_count++;
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
#pragma omp critical
@@ -1978,12 +1938,11 @@
mul_v3_v3fl(proxy[vd.i], val, fade);
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
}
@@ -2050,13 +2009,12 @@
mul_v3_v3fl(proxy[vd.i], val, fade);
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
}
@@ -2140,13 +2098,12 @@
mul_v3_v3fl(proxy[vd.i], val, fade);
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
}
@@ -2200,13 +2157,12 @@
mul_v3_v3fl(proxy[vd.i], val, fade);
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
}
@@ -2260,13 +2216,12 @@
mul_v3_v3fl(proxy[vd.i], val, fade);
- if(vd.mvert)
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
}
@@ -2332,16 +2287,158 @@
}
}
+float circle_eval(float circle_center[3], float radius_squared, float
co[3]){
+ return (circle_center[0]-co[0])*(circle_center[0]-co[0]) +
(circle_center[1]-co[1])*(circle_center[1]-co[1]) +
(circle_center[2]-co[2])*(circle_center[2]-co[2]) - radius_squared;
+}
+
+int circle_segment_test(float circle_center[3], float radius_squared,
float seg1[3], float seg2[3]){
+ float a = (seg1[0] - seg2[0])*(seg1[0] - seg2[0]) + (seg1[1] -
seg2[1])*(seg1[1] - seg2[1]) + (seg1[2] - seg2[2])*(seg1[2] - seg2[2]);
+ float b = 2.f * ( (seg2[0]-seg1[0])*(seg1[0]-circle_center[0]) +
(seg2[1]-seg1[1])*(seg1[1]-circle_center[1]) +
(seg2[2]-seg1[2])*(seg1[2]-circle_center[2]) );
+ float c = circle_center[0]*circle_center[0] +
circle_center[1]*circle_center[1] + circle_center[2]*circle_center[2] +
seg1[0]*seg1[0] + seg1[1]*seg1[1] + seg1[2]*seg1[2] - 2.f *
(circle_center[0]*seg1[0] + circle_center[1]*seg1[1] +
circle_center[2]*seg1[2]) - radius_squared;
+ float D = b*b - 4.f * a *c;
+ float u1,u2;
+
+ if ( D >= 0) {
+ u1 = (-b + sqrtf(D))/(2.f * a);
+ u2 = (-b - sqrtf(D))/(2.f * a);
+ if ((u1 >= 0.f && u1<= 1.f) || (u2 >= 0.f && u2 <= 1.f)) return 1;
//segment intersect at two points the sphere or one point is inside the
sphere
+ if ((u1 < 0.f && u2 >1.f) || (u2 < 0.f && u1 >1.f)) return 1; //segment
inside the sphere
+ }
+ else return 0;
+}
+
+static int circle_face_intersection(float circle_center[3], float radius,
struct EditFace *f){
+ if (circle_eval(circle_center, radius, f->v1->co) <= 0) return 1;
+ if (circle_eval(circle_center, radius, f->v2->co) <= 0) return 1;
+ if (circle_eval(circle_center, radius, f->v3->co) <= 0) return 1;
+ if (f->v4) if (circle_eval(circle_center, radius, f->v4->co) <= 0)
return 1;
+
+ if (circle_segment_test(circle_center, radius,
f->e1->v1->co,f->e1->v2->co) == 1) return 1;
+ if (circle_segment_test(circle_center, radius,
f->e2->v1->co,f->e2->v2->co) == 1) return 1;
+ if (circle_segment_test(circle_center, radius,
f->e3->v1->co,f->e3->v2->co) == 1) return 1;
+ if (f->e4) if (circle_segment_test(circle_center, radius,
f->e4->v1->co,f->e4->v2->co) == 1) return 1;
+
+ return 0;
+}
+
+#define SELECT 1
+static void mark_subdiv_faces(SculptSession *ss, PBVHNode *node, float
ext_radius, int edge_treshold){
+ int toteditface= node->totprim;
+ int *faces= node->prim_indices;
+ int i, isect = 0;
+
+ //extend selections, more select iterations means more derivates =
smooth detail transitions,
+ for(i = 0; i < toteditface; i++){
+ EditFace *f = ss->pbvh->editfaces[faces[i]];
+
+ if (fast_discard_tri(ss->cache->location, ext_radius , f->v1->co,
f->v2->co, f->v3->co)){ //does not work properly
+ //isect = circle_face_intersection(ss->cache->location, ext_radius , f);
+ //if (isect) {
+ f->f |= SELECT;
+
+ f->v1->f |= SELECT;
+ f->v2->f |= SELECT;
+ f->v3->f |= SELECT;
+ if (f->v4) f->v4->f |= SELECT;
+
+ f->v1->f1 = SELECT;
+ f->v2->f1 = SELECT;
+ f->v3->f1 = SELECT;
+ if (f->v4) f->v4->f1 = SELECT;
+ //} //faces, verts, f1
+ }//if (fast_discard_face
+ }
+
+ // second pass, extend selected verts, more iterations means more derivates
+ for(i = 0; i < toteditface; i++){
+ EditFace *f = ss->pbvh->editfaces[faces[i]];
+ int has_v4 = 0;
+ if (f->v4) if (f->v4->f1 == SELECT) has_v4 = 1;
+
+ if ((f->v1->f1 == SELECT) || (f->v2->f1 == SELECT) || (f->v3->f1 ==
SELECT) || has_v4){
+ if ((f->v1->count > edge_treshold) || (f->v2->count > edge_treshold)
|| (f->v3->count > edge_treshold))
+ f->f |= SELECT;
+ if (f->v4) if (f->v4->count > edge_treshold) f->f |= SELECT;
+
+ f->v1->f |= SELECT;
+ f->v2->f |= SELECT;
+ f->v3->f |= SELECT;
+ if (f->v4) f->v4->f |= SELECT;
+ } //f1->verts
+ }
+
+ // third pass, extend selected verts
+ for(i = 0; i < toteditface; i++){
+ EditFace *f = ss->pbvh->editfaces[faces[i]];
+ int has_v4 = 0;
+ if (f->v4) if (f->v4->f & SELECT) has_v4 = 1;
+
+ if ((f->v1->f & SELECT) | (f->v2->f & SELECT) | (f->v3->f & SELECT) |
has_v4) {
+ if ((f->v1->count > edge_treshold) || (f->v2->count > edge_treshold)
|| (f->v3->count > edge_treshold))
+ f->f |= SELECT;
+ if (f->v4) if (f->v4->count > edge_treshold) f->f |= SELECT;
+
+ f->v1->f1 = SELECT;
+ f->v2->f1 = SELECT;
+ f->v3->f1 = SELECT;
+ if (f->v4) f->v4->f1 = SELECT;
+ } //verts->f1
+ }
+}
+
+void sculpt_select_edges_uclay(SculptSession *ss, PBVHNode *node, float
ext_radius, float detail, int repeat, int edge_treshold){//edge_treshold:
fator to trigger edge splitting
+ int toteditface= node->totprim;
+ int *faces= node->prim_indices;
+
+ float diff[3];
+ float edgeLength;
+ int i = 0;
+ float dist1, dist2, dist3, s, d;
+
+ for(i = 0; i < toteditface; i++){
+ EditFace *f = ss->pbvh->editfaces[faces[i]];
+ if (f->f & SELECT)
+ {
+ float bigger = 0.f;
+ sub_v3_v3v3(diff, f->e1->v1->co, f->e1->v2->co);
+ dist1 = len_v3(diff);
+ bigger = dist1;
+
+ sub_v3_v3v3(diff, f->e2->v1->co, f->e2->v2->co);
+ dist2 = len_v3(diff);
+ if (bigger < dist2) bigger = dist2;
+
+ sub_v3_v3v3(diff, f->e3->v1->co, f->e3->v2->co);
+ dist3 = len_v3(diff);
+ if (bigger < dist3) bigger = dist3;
+
+ s = (dist1 + dist2 + dist3) * 0.5f; //area =
sqrtf(s*(s-dist1)*(s-dist2)*(s-dist3)); r = area/s; /* incircle radius */
+ d = 2.f * sqrtf((s-dist1)*(s-dist2)*(s-dist3)/s);
+
+ if (d > detail){
+ if (bigger == dist1) f->e1->f |= SELECT; //
+ else if (bigger == dist2) f->e2->f |= SELECT; //
+ else f->e3->f |= SELECT; //
+ }
+ } //if (efa->f & SELECT)
+ } //for(i = 0; i < toteditface; i++)....
+}
+
static void do_brush_action(Sculpt *sd, SculptSession *ss, Brush *brush)
{
SculptSearchSphereData data;
PBVHNode **nodes = NULL;
int n, totnode;
+ float ext_radius = 0.f;
/* Build a list of all nodes that are potentially within the brush's
area of influence */
data.ss = ss;
data.sd = sd;
data.radius_squared = ss->cache->radius_squared;
+ if (ss->uclay) {
+ data.radius_squared *= ss->uclay->offset;
+ ext_radius = data.radius_squared;
+ }
data.original = ELEM4(brush->sculpt_tool, SCULPT_TOOL_GRAB,
SCULPT_TOOL_ROTATE, SCULPT_TOOL_THUMB, SCULPT_TOOL_LAYER);
BLI_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes,
&totnode);
@@ -2351,8 +2448,15 @@
for (n= 0; n < totnode; n++) {
sculpt_undo_push_node(ss, nodes[n]);
BLI_pbvh_node_mark_update(nodes[n]);
- }
+ if (ss->uclay) {
+ float detail = 0.25f * (1.f - ss->uclay->detail + 0.2f) *
sqrtf(ext_radius); //nice radius detail function
+ int repeat = ss->uclay->relax;
+ mark_subdiv_faces(ss, nodes[n], ext_radius, 9);
+ sculpt_select_edges_uclay(ss, nodes[n], ext_radius, detail, repeat, 9);
+ }
+ }
+
/* Apply one type of brush action */
switch(brush->sculpt_tool){
case SCULPT_TOOL_DRAW:
@@ -2465,7 +2569,7 @@
sculpt_clip(sd, ss, vd.co, val);
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
BLI_pbvh_node_free_proxies(nodes[n]);
}
@@ -2503,7 +2607,7 @@
sculpt_clip(sd, ss, vd.co, val);
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
BLI_pbvh_node_free_proxies(nodes[n]);
@@ -2636,7 +2740,8 @@
{
DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
SculptSession *ss = ob->sculpt;
- MultiresModifierData *mmd= sculpt_multires_active(scene, ob);
+ MultiresModifierData *mmd= sculpt_multires_active(scene, ob);
+ UClayModifierData *ucmd = sculpt_uclay_active(scene,ob); //Mio
ss->ob= ob;
@@ -2652,7 +2757,17 @@
ss->mvert= NULL;
ss->mface= NULL;
ss->face_normals= NULL;
+ ss->uclay = NULL;
}
+ if (ucmd){
+ ss->uclay = ucmd;
+ ss->totvert = dm->getNumVerts(dm);
+ ss->totface = dm->getNumFaces(dm);
+ ss->mvert= NULL;
+ ss->mface= NULL;
+ ss->face_normals= NULL;
+ ss->multires = NULL;
+ }
else {
Mesh *me = get_mesh(ob);
ss->totvert = me->totvert;
@@ -2661,8 +2776,8 @@
ss->mface = me->mface;
ss->face_normals = NULL;
ss->multires = NULL;
- }
-
+ ss->uclay = NULL;
+ }
ss->pbvh = dm->getPBVH(ob, dm);
ss->fmap = (need_fmap && dm->getFaceMap)? dm->getFaceMap(ob, dm): NULL;
@@ -3008,6 +3123,7 @@
{
StrokeCache *cache = ss->cache;
Brush *brush = paint_brush(&sd->paint);
+ UClayModifierData *ucmd = ss->uclay;
int dx, dy;
@@ -3038,10 +3154,11 @@
if(cache->first_time) {
if (!brush_use_locked_size(brush)) {
cache->initial_radius= unproject_brush_radius(ss->ob, cache->vc,
cache->true_location, brush_size(brush));
- brush_set_unprojected_radius(brush, cache->initial_radius);
+ brush_set_unprojected_radius(brush, cache->initial_radius);
+
}
else {
- cache->initial_radius= brush_unprojected_radius(brush);
+ cache->initial_radius= brush_unprojected_radius(brush);
}
if (ELEM(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK))
@@ -3147,7 +3264,7 @@
if(ss->modifiers_active) {
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
Brush *brush = paint_brush(&sd->paint);
-
+
sculpt_update_mesh_elements(CTX_data_scene(C), ss->ob,
brush->sculpt_tool == SCULPT_TOOL_SMOOTH);
}
}
@@ -3278,9 +3395,9 @@
if(vd.no) VECCOPY(vd.no, unode->no[vd.i])
else normal_short_to_float_v3(vd.fno, unode->no[vd.i]);
- if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
BLI_pbvh_node_mark_update(nodes[n]);
}
@@ -3303,9 +3420,13 @@
SculptSession *ss = ob->sculpt;
ARegion *ar = CTX_wm_region(C);
MultiresModifierData *mmd = ss->multires;
+ UClayModifierData *ucmd = ss->uclay;
if(mmd)
multires_mark_as_modified(ob);
+ if(ucmd)
+ uclay_mark_as_modified(ob);
+
if(ob->derivedFinal) /* VBO no longer valid */
GPU_drawobject_free(ob->derivedFinal);
@@ -3582,18 +3703,26 @@
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
MultiresModifierData *mmd= sculpt_multires_active(scene, ob);
+ UClayModifierData *ucmd= sculpt_uclay_active(scene, ob);
int flush_recalc= 0;
(void)unused;
/* multires in sculpt mode could have different from object mode
subdivision level */
flush_recalc |= mmd && mmd->sculptlvl != mmd->lvl;
+
+ /* unlimited clay in sculpt mode could have different topology from
object mode */
+ flush_recalc |= (ucmd != NULL);
+
/* if object has got active modifiers, it's dm could be different in
sculpt mode */
//flush_recalc |= sculpt_modifiers_active(scene, ob);
if(ob->mode & OB_MODE_SCULPT) {
if(mmd)
multires_force_update(ob);
+
+ if(ucmd)
+ uclay_force_update(ob);
if(flush_recalc)
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
@@ -3655,3 +3784,4 @@
WM_operatortype_append(SCULPT_OT_set_persistent_base);
}
+
Index: source/blender/editors/sculpt_paint/sculpt_intern.h
===================================================================
--- source/blender/editors/sculpt_paint/sculpt_intern.h (revision 32564)
+++ source/blender/editors/sculpt_paint/sculpt_intern.h (working copy)
@@ -53,6 +53,7 @@
void sculpt_stroke_draw(struct SculptStroke *);
void sculpt_radialcontrol_start(int mode);
struct MultiresModifierData *sculpt_multires_active(struct Scene *scene,
struct Object *ob);
+struct UClayModifierData *sculpt_uclay_active(struct Scene *scene, struct
Object *ob);
struct Brush *sculptmode_brush(void);
//void do_symmetrical_brush_actions(struct Sculpt *sd, struct wmOperator
*wm, struct BrushAction *a, short *, short *);
@@ -108,6 +109,7 @@
void sculpt_undo_push_end(void);
struct MultiresModifierData *sculpt_multires_active(struct Scene *scene,
struct Object *ob);
+struct UClayModifierData *sculpt_uclay_active(struct Scene *scene, struct
Object *ob);
int sculpt_modifiers_active(Scene *scene, Object *ob);
void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]);
Index: source/blender/editors/sculpt_paint/sculpt_undo.c
===================================================================
--- source/blender/editors/sculpt_paint/sculpt_undo.c (revision 32564)
+++ source/blender/editors/sculpt_paint/sculpt_undo.c (working copy)
@@ -35,6 +35,7 @@
#include "BLI_math.h"
#include "BLI_ghash.h"
#include "BLI_threads.h"
+#include "BLI_editVert.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -73,6 +74,7 @@
SculptUndoNode *unode;
MVert *mvert;
MultiresModifierData *mmd;
+ UClayModifierData *ucmd;
int *index;
int i, j, update= 0;
@@ -154,9 +156,28 @@
swap_v3_v3(grid[i].co, co[0]);
}
}
+ /* else if(unode->toteditvert){
+ /* EditMesh (UClay) restore
+ EditVert *editvert = NULL;
+ float (*co)[3];
+
+ /* regular mesh restore
+ if(ss->totvert != unode->maxvert)
+ continue;
+ index= unode->index;
+ editvert= dm->getEditVerts(dm);
+
+ for(i=0; i<unode->toteditvert; i++) {
+ swap_v3_v3(editvert->co, unode->co[i]);
+ editvert = editvert->next;
+ //editvert->.flag |= ME_VERT_PBVH_UPDATE;
+ }
+ } //*/
+
update= 1;
}
+
if(update) {
/* we update all nodes still, should be more clever, but also
@@ -167,6 +188,9 @@
if((mmd=sculpt_multires_active(scene, ob)))
multires_mark_as_modified(ob);
+
+ if((ucmd=sculpt_uclay_active(scene, ob)))
+ uclay_mark_as_modified(ob); //Mio
if(ss->modifiers_active || ((Mesh*)ob->data)->id.us > 1)
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
@@ -186,6 +210,8 @@
MEM_freeN(unode->index);
if(unode->grids)
MEM_freeN(unode->grids);
+ // if(unode->editverts) //Mio
+ // MEM_freeN(unode->editverts);
if(unode->layer_disp)
MEM_freeN(unode->layer_disp);
}
@@ -211,8 +237,8 @@
ListBase *lb= undo_paint_push_get_list(UNDO_PAINT_MESH);
Object *ob= ss->ob;
SculptUndoNode *unode;
- int totvert, allvert, totgrid, maxgrid, gridsize, *grids;
-
+ int totvert, allvert, totgrid, maxgrid, gridsize, *grids, toteditvert,
*editverts;
+
/* list is manipulated by multiple threads, so we lock */
BLI_lock_thread(LOCK_CUSTOM1);
@@ -228,6 +254,7 @@
BLI_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert);
BLI_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
&maxgrid, &gridsize, NULL, NULL);
+ BLI_pbvh_node_get_editverts(ss->pbvh, node, &toteditvert, NULL,
&editverts); //Mio ver aqui
unode->totvert= totvert;
/* we will use this while sculpting, is mapalloc slow to access then? */
@@ -235,7 +262,7 @@
unode->no= MEM_mapallocN(sizeof(short)*3*allvert, "SculptUndoNode.no");
undo_paint_push_count_alloc(UNDO_PAINT_MESH, (sizeof(float)*3 +
sizeof(short)*3 + sizeof(int))*allvert);
BLI_addtail(lb, unode);
-
+
if(maxgrid) {
/* multires */
unode->maxgrid= maxgrid;
@@ -250,18 +277,18 @@
}
BLI_unlock_thread(LOCK_CUSTOM1);
-
+
/* copy threaded, hopefully this is the performance critical part */
{
PBVHVertexIter vd;
- BLI_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) {
+ BLI_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) {
copy_v3_v3(unode->co[vd.i], vd.co);
if(vd.no) VECCOPY(unode->no[vd.i], vd.no)
else normal_float_to_short_v3(unode->no[vd.i], vd.fno);
- if(vd.vert_indices) unode->index[vd.i]= vd.vert_indices[vd.i];
+ if(vd.vert_indices) unode->index[vd.i]= vd.vert_indices[vd.i];
}
- BLI_pbvh_vertex_iter_end;
+ BLI_pbvh_vertex_iter_end(vd);
}
if(unode->grids)
Index: source/blender/editors/space_outliner/outliner.c
===================================================================
--- source/blender/editors/space_outliner/outliner.c (revision 32564)
+++ source/blender/editors/space_outliner/outliner.c (working copy)
@@ -4351,6 +4351,8 @@
UI_icon_draw(x, y, ICON_MOD_SOLIDIFY); break;
case eModifierType_Screw:
UI_icon_draw(x, y, ICON_MOD_SCREW); break;
+ case eModifierType_UClay:
+ UI_icon_draw(x, y, ICON_MOD_PHYSICS); break;
default:
UI_icon_draw(x, y, ICON_DOT); break;
}
@@ -5691,3 +5693,4 @@
soops->storeflag &= ~SO_TREESTORE_REDRAW;
}
+
Index: source/blender/gpu/GPU_buffers.h
===================================================================
--- source/blender/gpu/GPU_buffers.h (revision 32564)
+++ source/blender/gpu/GPU_buffers.h (working copy)
@@ -142,6 +142,8 @@
int *grid_indices, int totgrid, int gridsize);
void GPU_update_grid_buffers(void *buffers_v, struct DMGridData **grids,
int *grid_indices, int totgrid, int gridsize, int smooth);
+void GPU_update_editmesh_buffers(void *buffers_v,struct EditVert
*editverts, int *editvert_indices, int toteditvert);
+void *GPU_build_editmesh_buffers(struct EditVert *editverts,struct
EditFace **editfaces, int toteditface, int toteditvert);
void GPU_draw_buffers(void *buffers);
void GPU_free_buffers(void *buffers);
Index: source/blender/gpu/intern/gpu_buffers.c
===================================================================
--- source/blender/gpu/intern/gpu_buffers.c (revision 32564)
+++ source/blender/gpu/intern/gpu_buffers.c (working copy)
@@ -41,6 +41,7 @@
#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_threads.h"
+#include "BLI_editVert.h"
#include "DNA_meshdata_types.h"
@@ -421,6 +422,11 @@
int totgrid;
int gridsize;
+ /* editmesh pointers */
+ EditFace **editfaces;
+ EditVert *editverts;
+ int toteditface;
+
unsigned int tot_tri, tot_quad;
} GPU_Buffers;
@@ -682,6 +688,121 @@
return buffers;
}
+
+void GPU_update_editmesh_buffers(void *buffers_v,struct EditVert *editverts,
+ int *editvert_indices, int toteditvert)
+{
+ GPU_Buffers *buffers = buffers_v;
+ VertexBufferFormat *vert_data;
+ int i;
+ EditVert *eve;
+
+ if(buffers->vert_buf) {
+ /* Build VBO , issues here*/
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+ sizeof(VertexBufferFormat) * toteditvert,
+ NULL, GL_STATIC_DRAW_ARB);
+ vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+
+ if(vert_data) {
+ for(eve= editverts; eve; eve= eve->next) {
+ //MVert *v = editvert + editvert_indices[i];
+ VertexBufferFormat *out = vert_data + i;
+
+ copy_v3_v3(out->co, eve->co);
+ memcpy(out->no, eve->no, sizeof(short) * 3);
+ i++;
+ }
+
+ glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+ }
+ else {
+ glDeleteBuffersARB(1, &buffers->vert_buf);
+ buffers->vert_buf = 0;
+ }
+
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ }
+
+ buffers->editverts = editverts;
+}
+
+void *GPU_build_editmesh_buffers(struct EditVert *editverts,struct
EditFace **editfaces, int toteditface, int toteditvert)
+{
+ GPU_Buffers *buffers; //improve this
+ unsigned short *tri_data;
+ int i, j, k, tottri = 0;
+
+ EditFace *efa;
+ EditVert *eve;
+
+ buffers = MEM_callocN(sizeof(GPU_Buffers), "GPU_Buffers");
+ buffers->index_type = GL_UNSIGNED_SHORT;
+
+ /* Count the number of triangles */
+ for(efa= editfaces; efa; efa= efa->next)
+ tottri += efa->v4 ? 2 : 1;
+
+
+ if(GL_ARB_vertex_buffer_object && !(U.gameflags & USER_DISABLE_VBO))
+ glGenBuffersARB(1, &buffers->index_buf);
+
+ if(buffers->index_buf) {
+ /* Generate index buffer object */
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
+ glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+ sizeof(unsigned short) * tottri * 3, NULL, GL_STATIC_DRAW_ARB);
+
+ /* Fill the triangle buffer */
+ tri_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ if(tri_data) {
+ for(efa= editfaces; efa; efa= efa->next) {
+ int v[3] = {efa->v1->co, efa->v2->co, efa->v3->co};
+
+ for(j = 0; j < (efa->v4 ? 2 : 1); ++j) {
+ for(k = 0; k < 3; ++k) {
+ // void *value, *key = SET_INT_IN_POINTER(v[k]);
+ int vbo_index;
+
+ // value = BLI_ghash_lookup(map, key);
+ vbo_index = 1; //GET_INT_FROM_POINTER(value);
+
+ // if(vbo_index < 0) {
+ // vbo_index = -vbo_index +
+ // tot_uniq_verts - 1;
+ // }
+
+ *tri_data = vbo_index;
+ ++tri_data;
+ }
+ v[0] = efa->v4->co;
+ v[1] = efa->v1->co;
+ v[2] = efa->v3->co;
+ }
+ }
+ glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
+ }
+ else {
+ glDeleteBuffersARB(1, &buffers->index_buf);
+ buffers->index_buf = 0;
+ }
+
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+ }
+
+ if(buffers->index_buf)
+ glGenBuffersARB(1, &buffers->vert_buf);
+ //GPU_update_editmesh_buffers(buffers, editverts, toteditvert);
+
+ buffers->tot_tri = tottri;
+
+ buffers->editfaces = editfaces;
+ buffers->toteditface = toteditface;
+
+ return buffers;
+}
+
void GPU_draw_buffers(void *buffers_v)
{
GPU_Buffers *buffers = buffers_v;
@@ -754,6 +875,26 @@
}
}
}
+ else if (buffers->toteditface){
+ /* fallback if we are out of memory */
+ int i;
+ for(i = 0; i < buffers->toteditface; ++i) {
+ EditFace *f = buffers->editfaces[buffers->face_indices[i]];
+
+ glBegin((f->v4)? GL_QUADS: GL_TRIANGLES);
+ glNormal3sv(f->v1->no);
+ glVertex3fv(f->v1->co);
+ glNormal3sv(f->v2->no);
+ glVertex3fv(f->v2->co);
+ glNormal3sv(f->v3->no);
+ glVertex3fv(f->v3->co);
+ if(f->v4) {
+ glNormal3sv(f->v4->no);
+ glVertex3fv(f->v4->co);
+ }
+ glEnd();
+ }
+ }
}
void GPU_free_buffers(void *buffers_v)
Index: source/blender/imbuf/intern/tiff.c
===================================================================
--- source/blender/imbuf/intern/tiff.c (revision 32564)
+++ source/blender/imbuf/intern/tiff.c (working copy)
@@ -2,7 +2,7 @@
* tiff.c
*
* $Id$
- *
+ *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -31,10 +31,10 @@
* already loaded the file into a memory buffer. libtiff is not well
* configured to handle files in memory, so a client wrapper is written to
* surround the memory and turn it into a virtual file. Currently, reading
- * of TIFF files is done using libtiff's RGBAImage support. This is a
+ * of TIFF files is done using libtiff's RGBAImage support. This is a
* high-level routine that loads all images as 32-bit RGBA, handling all the
* required conversions between many different TIFF types internally.
- *
+ *
* Saving supports RGB, RGBA and BW (greyscale) images correctly, with
* 8 bits per channel in all cases. The "deflate" compression algorithm is
* used to compress images.
@@ -45,7 +45,7 @@
#include <string.h>
#include "imbuf.h"
-
+
#include "BKE_global.h"
#include "BKE_utildefines.h"
@@ -58,11 +58,9 @@
#include "IMB_allocimbuf.h"
#include "IMB_filetype.h"
#include "IMB_filter.h"
-
#include "tiffio.h"
-
/***********************
* Local declarations. *
***********************/
@@ -98,7 +96,7 @@
(void)size;
}
-static int imb_tiff_DummyMapProc(thandle_t fd, tdata_t* pbase, toff_t*
psize)
+static int imb_tiff_DummyMapProc(thandle_t fd, tdata_t* pbase, toff_t*
psize)
{
(void)fd;
(void)pbase;
@@ -136,10 +134,10 @@
nRemaining = 0;
else
nRemaining = mfile->size - mfile->offset;
-
+
if(nCopy > nRemaining)
nCopy = nRemaining;
-
+
/* on EOF, return immediately and read (copy) nothing */
if(nCopy <= 0)
return (0);
@@ -207,7 +205,7 @@
break;
default:
/* no other types are supported - return an error */
- fprintf(stderr,
+ fprintf(stderr,
"imb_tiff_SeekProc: "
"Unsupported TIFF SEEK type.\n");
return (-1);
@@ -242,12 +240,12 @@
fprintf(stderr,"imb_tiff_CloseProc: !mfile || !mfile->mem!\n");
return (0);
}
-
+
/* virtually close the file */
mfile->mem = NULL;
mfile->offset = 0;
mfile->size = 0;
-
+
return (0);
}
@@ -280,7 +278,7 @@
memFile->offset = 0;
memFile->size = size;
- return TIFFClientOpen("(Blender TIFF Interface Layer)",
+ return TIFFClientOpen("(Blender TIFF Interface Layer)",
"r", (thandle_t)(memFile),
imb_tiff_ReadProc, imb_tiff_WriteProc,
imb_tiff_SeekProc, imb_tiff_CloseProc,
@@ -349,9 +347,9 @@
}
-/*
+/*
* Use the libTIFF scanline API to read a TIFF image.
- * This method is most flexible and can handle multiple different bit depths
+ * This method is most flexible and can handle multiple different bit depths
* and RGB channel orderings.
*/
static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
@@ -363,12 +361,12 @@
int ib_flag=0, row, chan;
float *fbuf=NULL;
unsigned short *sbuf=NULL;
-
+
TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bitspersample);
TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp); /* number of
'channels' */
TIFFGetField(image, TIFFTAG_PLANARCONFIG, &config);
scanline = TIFFScanlineSize(image);
-
+
if (bitspersample == 32) {
ib_flag = IB_rectfloat;
fbuf = (float *)_TIFFmalloc(scanline);
@@ -378,9 +376,9 @@
} else {
ib_flag = IB_rect;
}
-
+
tmpibuf= IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->depth, ib_flag);
-
+
/* simple RGBA image */
if (!(bitspersample == 32 || bitspersample == 16)) {
success |= TIFFReadRGBAImage(image, ibuf->x, ibuf->y, tmpibuf->rect, 0);
@@ -389,11 +387,11 @@
else if (config == PLANARCONFIG_CONTIG) {
for (row = 0; row < ibuf->y; row++) {
int ib_offset = ibuf->x*ibuf->y*4 - ibuf->x*4 * (row+1);
-
+
if (bitspersample == 32) {
success |= TIFFReadScanline(image, fbuf, row, 0);
scanline_contig_32bit(tmpibuf->rect_float+ib_offset, fbuf, ibuf->x,
spp);
-
+
} else if (bitspersample == 16) {
success |= TIFFReadScanline(image, sbuf, row, 0);
scanline_contig_16bit(tmpibuf->rect_float+ib_offset, sbuf, ibuf->x,
spp);
@@ -401,32 +399,32 @@
}
/* separate channels: RRRGGGBBB */
} else if (config == PLANARCONFIG_SEPARATE) {
-
+
/* imbufs always have 4 channels of data, so we iterate over all of them
* but only fill in from the TIFF scanline where necessary. */
for (chan = 0; chan < 4; chan++) {
for (row = 0; row < ibuf->y; row++) {
int ib_offset = ibuf->x*ibuf->y*4 - ibuf->x*4 * (row+1);
-
+
if (bitspersample == 32) {
if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */
memset(fbuf, 1.0, sizeof(fbuf));
else
success |= TIFFReadScanline(image, fbuf, row, chan);
scanline_separate_32bit(tmpibuf->rect_float+ib_offset, fbuf,
ibuf->x, chan);
-
+
} else if (bitspersample == 16) {
if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */
memset(sbuf, 65535, sizeof(sbuf));
else
success |= TIFFReadScanline(image, sbuf, row, chan);
scanline_separate_16bit(tmpibuf->rect_float+ib_offset, sbuf,
ibuf->x, chan);
-
+
}
}
}
}
-
+
if (bitspersample == 32)
_TIFFfree(fbuf);
else if (bitspersample == 16)
@@ -434,27 +432,27 @@
if(success) {
ibuf->profile = (bitspersample==32)?IB_PROFILE_LINEAR_RGB:IB_PROFILE_SRGB;
-
+
if(ENDIAN_ORDER == B_ENDIAN)
IMB_convert_rgba_to_abgr(tmpibuf);
if(premul) {
IMB_premultiply_alpha(tmpibuf);
ibuf->flags |= IB_premul;
}
-
+
/* assign rect last */
if (tmpibuf->rect_float)
ibuf->rect_float= tmpibuf->rect_float;
- else
+ else
ibuf->rect= tmpibuf->rect;
ibuf->mall |= ib_flag;
ibuf->flags |= ib_flag;
-
+
tmpibuf->mall &= ~ib_flag;
}
IMB_freeImBuf(tmpibuf);
-
+
return success;
}
@@ -505,15 +503,15 @@
TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height);
TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp);
-
+
ib_depth = (spp==3)?24:32;
-
+
ibuf = IMB_allocImBuf(width, height, ib_depth, 0);
if(ibuf) {
ibuf->ftype = TIF;
}
else {
- fprintf(stderr,
+ fprintf(stderr,
"imb_loadtiff: could not allocate memory for TIFF " \
"image.\n");
TIFFClose(image);
@@ -629,7 +627,7 @@
/**
* Saves a TIFF file.
*
- * ImBuf structures with 1, 3 or 4 bytes per pixel (GRAY, RGB, RGBA
+ * ImBuf structures with 1, 3 or 4 bytes per pixel (GRAY, RGB, RGBA
* respectively) are accepted, and interpreted correctly. Note that the
TIFF
* convention is to use pre-multiplied alpha, which can be achieved within
* Blender by setting "Premul" alpha handling. Other alpha conventions are
@@ -653,15 +651,15 @@
float *fromf = NULL;
int x, y, from_i, to_i, i;
int extraSampleTypes[1] = { EXTRASAMPLE_ASSOCALPHA };
-
+
/* check for a valid number of bytes per pixel. Like the PNG writer,
* the TIFF writer supports 1, 3 or 4 bytes per pixel, corresponding
* to gray, RGB, RGBA respectively. */
samplesperpixel = (uint16)((ibuf->depth + 7) >> 3);
if((samplesperpixel > 4) || (samplesperpixel == 2)) {
fprintf(stderr,
- "imb_savetiff: unsupported number of bytes per "
+ "imb_savetiff: unsupported number of bytes per "
"pixel: %d\n", samplesperpixel);
return (0);
}
@@ -675,7 +673,7 @@
if(flags & IB_mem) {
/* bork at the creation of a TIFF in memory */
fprintf(stderr,
- "imb_savetiff: creation of in-memory TIFF files is "
+ "imb_savetiff: creation of in-memory TIFF files is "
"not yet supported.\n");
return (0);
}
@@ -723,7 +721,7 @@
/* RGBA images */
TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1,
extraSampleTypes);
- TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
+ TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
PHOTOMETRIC_RGB);
}
else if(samplesperpixel == 3) {
@@ -746,7 +744,7 @@
if(pixels16) {
/* convert from float source */
float rgb[3];
-
+
if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
linearrgb_to_srgb_v3_v3(rgb, &fromf[from_i]);
else
@@ -756,7 +754,7 @@
to16[to_i+1] = FTOUSHORT(rgb[1]);
to16[to_i+2] = FTOUSHORT(rgb[2]);
to_i += 3; from_i+=3;
-
+
if (samplesperpixel == 4) {
to16[to_i+3] = FTOUSHORT(fromf[from_i+3]);
to_i++; from_i++;
Index: source/blender/makesdna/DNA_modifier_types.h
===================================================================
--- source/blender/makesdna/DNA_modifier_types.h (revision 32564)
+++ source/blender/makesdna/DNA_modifier_types.h (working copy)
@@ -66,9 +66,10 @@
eModifierType_ShapeKey,
eModifierType_Solidify,
eModifierType_Screw,
+ eModifierType_UClay,
/* placeholder, keep this so durian files load in
* trunk with the correct modifier once its merged */
- eModifierType_Warp,
+ eModifierType_Warp,
NUM_MODIFIER_TYPES
} ModifierType;
@@ -442,6 +443,15 @@
ModifierData modifier;
} SoftbodyModifierData;
+typedef struct UClayModifierData {
+ ModifierData modifier;
+
+ float detail, offset;
+ float smoothness;
+ int relax;
+
+} UClayModifierData;
+
typedef struct ClothModifierData {
ModifierData modifier;
Index: source/blender/makesrna/intern/rna_modifier.c
===================================================================
--- source/blender/makesrna/intern/rna_modifier.c (revision 32564)
+++ source/blender/makesrna/intern/rna_modifier.c (working copy)
@@ -85,6 +85,7 @@
{eModifierType_Smoke, "SMOKE", ICON_MOD_SMOKE, "Smoke", ""},
{eModifierType_Softbody, "SOFT_BODY", ICON_MOD_SOFT, "Soft Body", ""},
{eModifierType_Surface, "SURFACE", ICON_MOD_PHYSICS, "Surface", ""},
+ {eModifierType_UClay, "UCLAY", ICON_MOD_SOFT, "UClay", ""},
{0, NULL, 0, NULL, NULL}};
#ifdef RNA_RUNTIME
@@ -175,6 +176,8 @@
return &RNA_SolidifyModifier;
case eModifierType_Screw:
return &RNA_ScrewModifier;
+ case eModifierType_UClay:
+ return &RNA_UClayModifier;
default:
return &RNA_Modifier;
}
@@ -2085,6 +2088,36 @@
RNA_def_struct_ui_icon(srna, ICON_MOD_PHYSICS);
}
+static void rna_def_modifier_uclay(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "UClayModifier", "Modifier");
+ RNA_def_struct_ui_text(srna, "Unlimited Clay Modifier", "Unlimited Clay
Modifier for sculpting");
+ RNA_def_struct_sdna(srna, "UClayModifierData");
+ RNA_def_struct_ui_icon(srna, ICON_MOD_PHYSICS);
+
+ prop= RNA_def_property(srna, "detail", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.001, 1.0);
+ RNA_def_property_ui_range(prop, 0.005, 1.0, 0.5, 3);
+ RNA_def_property_ui_text(prop, "Detail", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "smoothness", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "smoothness");
+ RNA_def_property_range(prop, 0.0, 100.0);
+ RNA_def_property_ui_range(prop, 0.0, 10, 0.25, 2);
+ RNA_def_property_ui_text(prop, "Smoothness", "Subdivission smoothness");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "relax", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 0, 1000);
+ RNA_def_property_ui_range(prop, 0, 1000, 0, 0);
+ RNA_def_property_ui_text(prop, "Relax", "Vertex relaxing iteration");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+}
+
static void rna_def_modifier_solidify(BlenderRNA *brna)
{
StructRNA *srna;
@@ -2333,6 +2366,7 @@
rna_def_modifier_smoke(brna);
rna_def_modifier_solidify(brna);
rna_def_modifier_screw(brna);
+ rna_def_modifier_uclay(brna);
}
#endif
Index: source/blender/makesrna/intern/rna_sequencer.c
===================================================================
--- source/blender/makesrna/intern/rna_sequencer.c (revision 32564)
+++ source/blender/makesrna/intern/rna_sequencer.c (working copy)
@@ -48,7 +48,7 @@
static float to_dB(float x)
{
- return logf(x * x + 1e-30f) * 4.34294480f;
+ return 4.34294480f * logf(x * x + 1e-30f) ;
}
static float from_dB(float x)
Index: source/blender/makesrna/RNA_access.h
===================================================================
--- source/blender/makesrna/RNA_access.h (revision 32564)
+++ source/blender/makesrna/RNA_access.h (working copy)
@@ -562,6 +562,7 @@
extern StructRNA RNA_WorldTextureSlot;
extern StructRNA RNA_XnorController;
extern StructRNA RNA_XorController;
+extern StructRNA RNA_UClayModifier;
/* Pointer
@@ -939,3 +940,4 @@
#endif /* RNA_ACCESS */
+
Index: source/blender/modifiers/intern/MOD_uclay.c
===================================================================
--- source/blender/modifiers/intern/MOD_uclay.c (revision 0)
+++ source/blender/modifiers/intern/MOD_uclay.c (revision 0)
@@ -0,0 +1,135 @@
+/*
+* $Id: MOD_uclay.c 28152 2010-5-24 farsthary $
+*
+* ***** 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.
+*
+* The Original Code is Copyright (C) 2005 by the Blender Foundation.
+* All rights reserved.
+*
+* Contributor(s): Raul Fernandez Hernandez
+*
+* ***** END GPL LICENSE BLOCK *****
+*
+*/
+
+
+#include "DNA_scene_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_cdderivedmesh.h"
+#include "BKE_particle.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_utildefines.h"
+#include "BKE_bmesh.h"
+#include "BKE_multires.h"
+#include "BKE_paint.h"
+
+#include "BLI_math.h"
+#include "BLI_linklist.h"
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_pbvh.h"
+
+#include "MOD_modifiertypes.h"
+
+//---------
+#include "BKE_brush.h"
+#include "BKE_customdata.h"
+#include "BKE_depsgraph.h"
+#include "BKE_global.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+//-----------
+
+#include
"C:\Blender_Build\blenderSVN\source\blender\editors\include\ED_mesh.h"
+
+struct StrokeCache;
+
+
+static void initData(ModifierData *md)
+{
+ UClayModifierData *ucmd = (UClayModifierData*) md;
+
+ ucmd->detail = 0.5f;
+ ucmd->smoothness = 0.25f;
+ ucmd->relax = 0;
+ ucmd->offset = 1.5f;
+}
+
+static void copyData(ModifierData *md, ModifierData *target)
+{
+ UClayModifierData *ucmd = (UClayModifierData*) md;
+ UClayModifierData *tucmd = (UClayModifierData*) target;
+
+ tucmd->detail = ucmd->detail;
+ tucmd->smoothness = ucmd->smoothness;
+ tucmd->relax = ucmd->relax;
+ tucmd->offset = ucmd->offset;
+}
+
+static DerivedMesh *applyModifier(
+ ModifierData *md, Object *ob, DerivedMesh *dm,
+ int useRenderParams, int isFinalCalc)
+{
+ SculptSession *ss= ob->sculpt;
+ int sculpting= (ob->mode & OB_MODE_SCULPT) && ss;
+ float radius = 10.f; //A big threshold to ensure that theres no
subdivission if no sculpting, odd?
+ UClayModifierData *ucmd = (UClayModifierData*)md;
+ DerivedMesh *result = NULL;
+ if(sculpting && ss->cache != NULL) radius = ss->cache->radius;
+
+ result = uclay_dm_create_from_derived(ucmd, 0, dm, ob, md->scene,
radius, useRenderParams, isFinalCalc);
+
+ if(result == dm)
+ return dm;
+
+ if(useRenderParams || !isFinalCalc) {
+ DerivedMesh *cddm= CDDM_copy(result);
+ result->release(result);
+ result= cddm;
+ } else if(sculpting)
+ ss->pbvh= result->getPBVH(ob, result);
+
+ return result;
+}
+
+
+ModifierTypeInfo modifierType_UClay = {
+ /* name */ "UClay",
+ /* structName */ "UClayModifierData",
+ /* structSize */ sizeof(UClayModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh
+ | eModifierTypeFlag_RequiresOriginalData,
+ /* copyData */ copyData,
+ /* deformVerts */ 0,
+ /* deformVertsEM */ 0,
+ /* deformMatricesEM */ 0,
+ /* applyModifier */ applyModifier,
+ /* applyModifierEM */ 0,
+ /* initData */ initData,
+ /* requiredDataMask */ 0,
+ /* freeData */ 0,
+ /* isDisabled */ 0,
+ /* updateDepgraph */ 0,
+ /* dependsOnTime */ 0,
+ /* foreachObjectLink */ 0,
+ /* foreachIDLink */ 0,
+};
Index: source/blender/modifiers/intern/MOD_util.c
===================================================================
--- source/blender/modifiers/intern/MOD_util.c (revision 32564)
+++ source/blender/modifiers/intern/MOD_util.c (working copy)
@@ -182,5 +182,6 @@
INIT_TYPE(ShapeKey);
INIT_TYPE(Solidify);
INIT_TYPE(Screw);
+ INIT_TYPE(UClay);
#undef INIT_TYPE
}
Index: source/blender/modifiers/MOD_modifiertypes.h
===================================================================
--- source/blender/modifiers/MOD_modifiertypes.h (revision 32564)
+++ source/blender/modifiers/MOD_modifiertypes.h (working copy)
@@ -67,6 +67,7 @@
extern ModifierTypeInfo modifierType_ShapeKey;
extern ModifierTypeInfo modifierType_Solidify;
extern ModifierTypeInfo modifierType_Screw;
+extern ModifierTypeInfo modifierType_UClay;
/* MOD_util.c */
void modifier_type_init(ModifierTypeInfo *types[]);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
- Participe en Universidad 2012, del 13 al 17 de febrero de 2012. Habana. Cuba. http://www.congresouniversidad.cu
- Consulte la Enciclopedia Colaborativa Cubana. http://www.ecured.cu
More information about the Bf-committers
mailing list