Revision: 25391
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25391
Author:   campbellbarton
Date:     2009-12-15 00:35:13 +0100 (Tue, 15 Dec 2009)

Log Message:
-----------
solidify from 2.4x (ported from python to C)
- shell_angle_to_dist() was using degrees

Modified Paths:
--------------
    trunk/blender/release/scripts/ui/space_view3d.py
    trunk/blender/source/blender/blenlib/intern/math_base.c
    trunk/blender/source/blender/editors/include/ED_mesh.h
    trunk/blender/source/blender/editors/mesh/editmesh_lib.c
    trunk/blender/source/blender/editors/mesh/editmesh_mods.c
    trunk/blender/source/blender/editors/mesh/mesh_intern.h
    trunk/blender/source/blender/editors/mesh/mesh_ops.c

Modified: trunk/blender/release/scripts/ui/space_view3d.py
===================================================================
--- trunk/blender/release/scripts/ui/space_view3d.py    2009-12-14 23:19:59 UTC 
(rev 25390)
+++ trunk/blender/release/scripts/ui/space_view3d.py    2009-12-14 23:35:13 UTC 
(rev 25391)
@@ -1202,6 +1202,7 @@
         layout.operator("mesh.edge_face_add")
         layout.operator("mesh.fill")
         layout.operator("mesh.beauty_fill")
+        layout.operator("mesh.solidify")
 
         layout.separator()
 

Modified: trunk/blender/source/blender/blenlib/intern/math_base.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_base.c     2009-12-14 
23:19:59 UTC (rev 25390)
+++ trunk/blender/source/blender/blenlib/intern/math_base.c     2009-12-14 
23:35:13 UTC (rev 25391)
@@ -100,7 +100,7 @@
  * the distance gets very high, 180d would be inf, but this case isn't valid */
 float shell_angle_to_dist(const float angle)
 {
-       return (angle < SMALL_NUMBER) ? 1.0f : fabsf(1.0f / cosf(angle * 
(M_PI/180.0f)));
+       return (angle < SMALL_NUMBER) ? 1.0f : fabsf(1.0f / cosf(angle));
 }
 
 /* used for zoom values*/

Modified: trunk/blender/source/blender/editors/include/ED_mesh.h
===================================================================
--- trunk/blender/source/blender/editors/include/ED_mesh.h      2009-12-14 
23:19:59 UTC (rev 25390)
+++ trunk/blender/source/blender/editors/include/ED_mesh.h      2009-12-14 
23:35:13 UTC (rev 25391)
@@ -147,6 +147,9 @@
 void           EM_add_data_layer(struct EditMesh *em, struct CustomData *data, 
int type);
 void           EM_free_data_layer(struct EditMesh *em, struct CustomData 
*data, int type);
 
+void           EM_make_hq_normals(struct EditMesh *em);
+void           EM_solidify(struct EditMesh *em, float dist);
+
 /* editmesh_mods.c */
 extern unsigned int em_vertoffs, em_solidoffs, em_wireoffs;
 

Modified: trunk/blender/source/blender/editors/mesh/editmesh_lib.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_lib.c    2009-12-14 
23:19:59 UTC (rev 25390)
+++ trunk/blender/source/blender/editors/mesh/editmesh_lib.c    2009-12-14 
23:35:13 UTC (rev 25391)
@@ -49,6 +49,7 @@
 #include "BLI_blenlib.h"
 #include "BLI_math.h"
 #include "BLI_editVert.h"
+#include "BLI_edgehash.h"
 
 #include "BKE_customdata.h"
 #include "BKE_context.h"
@@ -2287,3 +2288,149 @@
                return 1;
        return 0;
 }
+
+/* higher quality normals */
+
+/* NormalCalc */
+/* NormalCalc modifier: calculates higher quality normals
+*/
+
+/* each edge uses this to  */
+typedef struct EdgeFaceRef {
+       int f1; /* init as -1 */
+       int f2;
+} EdgeFaceRef;
+
+void EM_make_hq_normals(EditMesh *em)
+{
+       EditFace *efa;
+       EditVert *eve;
+       int i;
+
+       EdgeHash *edge_hash = BLI_edgehash_new();
+       EdgeHashIterator *edge_iter;
+       int edge_ref_count = 0;
+       int ed_v1, ed_v2; /* use when getting the key */
+       EdgeFaceRef *edge_ref_array = MEM_callocN(em->totedge * 
sizeof(EdgeFaceRef), "Edge Connectivity");
+       EdgeFaceRef *edge_ref;
+       float edge_normal[3];
+
+       EM_init_index_arrays(em, 1, 1, 1);
+
+       for(eve= em->verts.first, i=0; eve; eve= eve->next, i++) {
+               zero_v3(eve->no);
+               eve->tmp.l= i;
+       }
+
+       /* This function adds an edge hash if its not there, and adds the face 
index */
+#define NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(EDV1, EDV2); \
+                       edge_ref = (EdgeFaceRef 
*)BLI_edgehash_lookup(edge_hash, EDV1, EDV2); \
+                       if (!edge_ref) { \
+                               edge_ref = &edge_ref_array[edge_ref_count]; 
edge_ref_count++; \
+                               edge_ref->f1=i; \
+                               edge_ref->f2=-1; \
+                               BLI_edgehash_insert(edge_hash, EDV1, EDV2, 
edge_ref); \
+                       } else { \
+                               edge_ref->f2=i; \
+                       }
+
+
+       efa= em->faces.first;
+       for(i = 0; i < em->totface; i++, efa= efa->next) {
+               if(efa->v4) {
+                       NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(efa->v1->tmp.l, 
efa->v2->tmp.l);
+                       NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(efa->v2->tmp.l, 
efa->v3->tmp.l);
+                       NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(efa->v3->tmp.l, 
efa->v4->tmp.l);
+                       NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(efa->v4->tmp.l, 
efa->v1->tmp.l);
+               } else {
+                       NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(efa->v1->tmp.l, 
efa->v2->tmp.l);
+                       NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(efa->v2->tmp.l, 
efa->v3->tmp.l);
+                       NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(efa->v3->tmp.l, 
efa->v1->tmp.l);
+               }
+       }
+
+#undef NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE
+
+
+       for(edge_iter = BLI_edgehashIterator_new(edge_hash); 
!BLI_edgehashIterator_isDone(edge_iter); BLI_edgehashIterator_step(edge_iter)) {
+               /* Get the edge vert indicies, and edge value (the face 
indicies that use it)*/
+               BLI_edgehashIterator_getKey(edge_iter, (int*)&ed_v1, 
(int*)&ed_v2);
+               edge_ref = BLI_edgehashIterator_getValue(edge_iter);
+
+               if (edge_ref->f2 != -1) {
+                       /* We have 2 faces using this edge, calculate the edges 
normal
+                        * using the angle between the 2 faces as a weighting */
+                       add_v3_v3v3(edge_normal, 
EM_get_face_for_index(edge_ref->f1)->n, EM_get_face_for_index(edge_ref->f2)->n);
+                       normalize_v3(edge_normal);
+                       mul_v3_fl(edge_normal, 
angle_normalized_v3v3(EM_get_face_for_index(edge_ref->f1)->n, 
EM_get_face_for_index(edge_ref->f2)->n));
+               } else {
+                       /* only one face attached to that edge */
+                       /* an edge without another attached- the weight on this 
is
+                        * undefined, M_PI/2 is 90d in radians and that seems 
good enough */
+                       VECCOPY(edge_normal, 
EM_get_face_for_index(edge_ref->f1)->n)
+                       mul_v3_fl(edge_normal, M_PI/2);
+               }
+               add_v3_v3(EM_get_vert_for_index(ed_v1)->no, edge_normal );
+               add_v3_v3(EM_get_vert_for_index(ed_v2)->no, edge_normal );
+
+
+       }
+       BLI_edgehashIterator_free(edge_iter);
+       BLI_edgehash_free(edge_hash, NULL);
+       MEM_freeN(edge_ref_array);
+
+       /* normalize vertex normals and assign */
+       for(eve= em->verts.first; eve; eve= eve->next)
+               normalize_v3(eve->no);
+
+       EM_free_index_arrays();
+}
+
+#define FLT_EPSILON 0.00001
+void EM_solidify(EditMesh *em, float dist)
+{
+       EditFace *efa;
+       EditVert *eve;
+       int *vert_users= MEM_callocN(sizeof(int) * em->totvert, "EM_offset");
+       float *vert_angles= MEM_callocN(sizeof(float) * em->totvert, 
"EM_offset");
+       float angle;
+       int i;
+
+       for(eve= em->verts.first, i=0; eve; eve= eve->next, i++) {
+               eve->tmp.l= i;
+       }
+
+       efa= em->faces.first;
+       for(i = 0; i < em->totface; i++, efa= efa->next) {
+
+               if(!(efa->f & SELECT))
+                       continue;
+
+               angle= angle_normalized_v3v3(efa->v1->no, efa->n);
+               vert_angles[efa->v1->tmp.l]+= shell_angle_to_dist(angle);
+               vert_users[efa->v1->tmp.l]++;
+
+               angle= angle_normalized_v3v3(efa->v2->no, efa->n);
+               vert_angles[efa->v2->tmp.l]+= shell_angle_to_dist(angle);
+               vert_users[efa->v2->tmp.l]++;
+
+               angle= angle_normalized_v3v3(efa->v3->no, efa->n);
+               vert_angles[efa->v3->tmp.l]+= shell_angle_to_dist(angle);
+               vert_users[efa->v3->tmp.l]++;
+
+               if(efa->v4) {
+                       angle= angle_normalized_v3v3(efa->v4->no, efa->n);
+                       vert_angles[efa->v4->tmp.l]+= 
shell_angle_to_dist(angle);
+                       vert_users[efa->v4->tmp.l]++;
+               }
+       }
+
+       for(eve= em->verts.first, i=0; eve; eve= eve->next, i++) {
+               if(vert_users[i]) { /* zero if unselected */
+                       madd_v3_v3fl(eve->co, eve->no, dist * (vert_angles[i] / 
(float)vert_users[i]));
+               }
+       }
+
+       MEM_freeN(vert_users);
+       MEM_freeN(vert_angles);
+}

Modified: trunk/blender/source/blender/editors/mesh/editmesh_mods.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_mods.c   2009-12-14 
23:19:59 UTC (rev 25390)
+++ trunk/blender/source/blender/editors/mesh/editmesh_mods.c   2009-12-14 
23:35:13 UTC (rev 25391)
@@ -4542,3 +4542,46 @@
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+
+static int solidify_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
+       float nor[3] = {0,0,1};
+
+       float thickness= RNA_float_get(op->ptr, "thickness");
+
+       extrudeflag(obedit, em, SELECT, nor);
+       EM_make_hq_normals(em);
+       EM_solidify(em, thickness);
+
+
+       /* update vertex normals too */
+       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 MESH_OT_solidify(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Solidify";
+       ot->description= "Make the mesh solid.";
+       ot->idname= "MESH_OT_solidify";
+
+       /* api callbacks */
+       ot->exec= solidify_exec;
+       ot->poll= ED_operator_editmesh;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       RNA_def_float(ot->srna, "thickness", 0.1f, -FLT_MAX, FLT_MAX, 
"thickness", "", -10.0f, 10.0f);
+}

Modified: trunk/blender/source/blender/editors/mesh/mesh_intern.h
===================================================================
--- trunk/blender/source/blender/editors/mesh/mesh_intern.h     2009-12-14 
23:19:59 UTC (rev 25390)
+++ trunk/blender/source/blender/editors/mesh/mesh_intern.h     2009-12-14 
23:35:13 UTC (rev 25391)
@@ -164,7 +164,9 @@
 void MESH_OT_mark_sharp(struct wmOperatorType *ot);
 void MESH_OT_vertices_smooth(struct wmOperatorType *ot);
 void MESH_OT_flip_normals(struct wmOperatorType *ot);
+void MESH_OT_solidify(struct wmOperatorType *ot);
 
+
 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);

Modified: trunk/blender/source/blender/editors/mesh/mesh_ops.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/mesh_ops.c        2009-12-14 
23:19:59 UTC (rev 25390)
+++ trunk/blender/source/blender/editors/mesh/mesh_ops.c        2009-12-14 
23:35:13 UTC (rev 25391)
@@ -151,6 +151,8 @@
        
        WM_operatortype_append(MESH_OT_edgering_select);
        WM_operatortype_append(MESH_OT_loopcut);
+
+       WM_operatortype_append(MESH_OT_solidify);
 }
 
 int ED_operator_editmesh_face_select(bContext *C)


_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to