==Mesh modeling==
authorChris Want <cwant@ualberta.ca>
Sat, 10 Jun 2006 04:48:56 +0000 (04:48 +0000)
committerChris Want <cwant@ualberta.ca>
Sat, 10 Jun 2006 04:48:56 +0000 (04:48 +0000)
A modification of how 'Extrude Region' behaves on the line of
symmetry when a mirror modifier is used. If 'Do clipping' is
selected, and there is an edge selected on the line of symmetry
that is connected to a selected face, that edge no longer gets
extruded into a face lying on the symmetry line. In pictures,
here is how the old behavior compares to the new behavior:

http://bebop.cns.ualberta.ca/~cwant/mirror_extrude_region

I think this new behavior is consistent with what most users of
the mirror modifiers would want, but if not please say so!

Also: Test, test, test!

source/blender/src/editmesh_lib.c

index ad8788b1bbbae07245b536982497f96fd240af89..71903f1d437792a06638c4ea01023f6ecd7f103d 100644 (file)
@@ -49,6 +49,7 @@ editmesh_lib: generic (no UI, no menus) operations/evaluators for editmesh data
 
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 
@@ -941,6 +942,7 @@ static short extrudeflag_edge(short flag, float *nor)
        EditEdge *eed, *nexted;
        EditFace *efa, *nextfa;
        short del_old= 0;
        EditEdge *eed, *nexted;
        EditFace *efa, *nextfa;
        short del_old= 0;
+       ModifierData *md= G.obedit->modifiers.first;
        
        if(G.obedit==0 || get_mesh(G.obedit)==0) return 0;
        
        
        if(G.obedit==0 || get_mesh(G.obedit)==0) return 0;
        
@@ -993,6 +995,40 @@ static short extrudeflag_edge(short flag, float *nor)
                }
        }
        
                }
        }
        
+       /* If a mirror modifier with clipping is on, we need to adjust some 
+        * of the cases above to handle edges on the line of symmetry.
+        */
+       for (; md; md=md->next) {
+               if (md->type==eModifierType_Mirror) {
+                       MirrorModifierData *mmd = (MirrorModifierData*) md;     
+               
+                       if(mmd->flag & MOD_MIR_CLIPPING) {
+                               for (eed= em->edges.first; eed; eed= eed->next) {
+                                       if(eed->f2 == 1) {
+
+                                               switch(mmd->axis){
+                                                       case 0:
+                                                               if ( (fabs(eed->v1->co[0]) < mmd->tolerance) &&
+                                                                        (fabs(eed->v2->co[0]) < mmd->tolerance) )
+                                                                       ++eed->f2;
+                                                               break;
+                                                       case 1:
+                                                               if ( (fabs(eed->v1->co[1]) < mmd->tolerance) &&
+                                                                        (fabs(eed->v2->co[1]) < mmd->tolerance) )
+                                                                       ++eed->f2;
+                                                               break;
+                                                       case 2:
+                                                               if ( (fabs(eed->v1->co[2]) < mmd->tolerance) &&
+                                                                        (fabs(eed->v2->co[2]) < mmd->tolerance) )
+                                                                       ++eed->f2;
+                                                               break;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
        set_edge_directions_f2(2);
        
        /* step 1.5: if *one* selected face has edge with unselected face; remove old selected faces */
        set_edge_directions_f2(2);
        
        /* step 1.5: if *one* selected face has edge with unselected face; remove old selected faces */
@@ -1141,6 +1177,7 @@ short extrudeflag_vert(short flag, float *nor)
        EditEdge *eed, *e1, *e2, *e3, *e4, *nexted;
        EditFace *efa, *efa2, *nextvl;
        short sel=0, del_old= 0, is_face_sel=0;
        EditEdge *eed, *e1, *e2, *e3, *e4, *nexted;
        EditFace *efa, *efa2, *nextvl;
        short sel=0, del_old= 0, is_face_sel=0;
+       ModifierData *md= G.obedit->modifiers.first;
 
        if(G.obedit==0 || get_mesh(G.obedit)==0) return 0;
 
 
        if(G.obedit==0 || get_mesh(G.obedit)==0) return 0;
 
@@ -1225,6 +1262,40 @@ short extrudeflag_vert(short flag, float *nor)
                efa->f1==1 : duplicate this face
        */
 
                efa->f1==1 : duplicate this face
        */
 
+       /* If a mirror modifier with clipping is on, we need to adjust some 
+        * of the cases above to handle edges on the line of symmetry.
+        */
+       for (; md; md=md->next) {
+               if (md->type==eModifierType_Mirror) {
+                       MirrorModifierData *mmd = (MirrorModifierData*) md;     
+               
+                       if(mmd->flag & MOD_MIR_CLIPPING) {
+                               for (eed= em->edges.first; eed; eed= eed->next) {
+                                       if(eed->f2 == 2) {
+
+                                               switch(mmd->axis){
+                                                       case 0:
+                                                               if ( (fabs(eed->v1->co[0]) < mmd->tolerance) &&
+                                                                        (fabs(eed->v2->co[0]) < mmd->tolerance) )
+                                                                       ++eed->f2;
+                                                               break;
+                                                       case 1:
+                                                               if ( (fabs(eed->v1->co[1]) < mmd->tolerance) &&
+                                                                        (fabs(eed->v2->co[1]) < mmd->tolerance) )
+                                                                       ++eed->f2;
+                                                               break;
+                                                       case 2:
+                                                               if ( (fabs(eed->v1->co[2]) < mmd->tolerance) &&
+                                                                        (fabs(eed->v2->co[2]) < mmd->tolerance) )
+                                                                       ++eed->f2;
+                                                               break;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
        /* copy all selected vertices, */
        /* write pointer to new vert in old struct at eve->tmp.v */
        eve= em->verts.last;
        /* copy all selected vertices, */
        /* write pointer to new vert in old struct at eve->tmp.v */
        eve= em->verts.last;