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