Fix T51665: No orientation for nurbs, polygons
authorCampbell Barton <ideasman42@gmail.com>
Mon, 10 Jul 2017 04:37:20 +0000 (14:37 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 10 Jul 2017 06:29:54 +0000 (16:29 +1000)
source/blender/blenkernel/BKE_curve.h
source/blender/blenkernel/intern/curve.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_orientations.c

index 0d382c8a49cf64e8f4445d8881da8586ac1dafd0..635e999dd9585a524a14be65383c5761a55c19d1 100644 (file)
@@ -198,6 +198,7 @@ void BKE_nurb_bezt_calc_normal(struct Nurb *nu, struct BezTriple *bezt, float r_
 void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_plane[3]);
 
 void BKE_nurb_bpoint_calc_normal(struct Nurb *nu, struct BPoint *bp, float r_normal[3]);
+void BKE_nurb_bpoint_calc_plane(struct Nurb *nu, struct BPoint *bp, float r_plane[3]);
 
 void BKE_nurb_handle_calc(struct BezTriple *bezt, struct BezTriple *prev,  struct BezTriple *next,
                           const bool is_fcurve);
index 8b32109cf2b052d91e819548dfb9bdc1ca044a22..e4637e709f4109c7ff352de387a3789e1a23ae53 100644 (file)
@@ -856,6 +856,34 @@ void BKE_nurb_bpoint_calc_normal(struct Nurb *nu, struct BPoint *bp, float r_nor
        normalize_v3(r_normal);
 }
 
+void BKE_nurb_bpoint_calc_plane(struct Nurb *nu, BPoint *bp, float r_plane[3])
+{
+       BPoint *bp_prev = BKE_nurb_bpoint_get_prev(nu, bp);
+       BPoint *bp_next = BKE_nurb_bpoint_get_next(nu, bp);
+
+       float dir_prev[3] = {0.0f}, dir_next[3] = {0.0f};
+
+       if (bp_prev) {
+               sub_v3_v3v3(dir_prev, bp_prev->vec, bp->vec);
+               normalize_v3(dir_prev);
+       }
+       if (bp_next) {
+               sub_v3_v3v3(dir_next, bp->vec, bp_next->vec);
+               normalize_v3(dir_next);
+       }
+       cross_v3_v3v3(r_plane, dir_prev, dir_next);
+
+       /* matches with bones more closely */
+       {
+               float dir_mid[3], tvec[3];
+               add_v3_v3v3(dir_mid, dir_prev, dir_next);
+               cross_v3_v3v3(tvec, r_plane, dir_mid);
+               copy_v3_v3(r_plane, tvec);
+       }
+
+       normalize_v3(r_plane);
+}
+
 /* ~~~~~~~~~~~~~~~~~~~~Non Uniform Rational B Spline calculations ~~~~~~~~~~~ */
 
 
index c15d11cdb6ee0baa3578a43957e4a34c7c778c3a..4429d19613a4339a64371f201afd6ce9003f024e 100644 (file)
@@ -1775,6 +1775,26 @@ static void createTransCurveVerts(TransInfo *t)
                        for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
                                if (bp->hide == 0) {
                                        if (is_prop_edit || (bp->f1 & SELECT)) {
+                                               float axismtx[3][3];
+
+                                               if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
+                                                       if (nu->pntsv == 1) {
+                                                               float normal[3], plane[3];
+
+                                                               BKE_nurb_bpoint_calc_normal(nu, bp, normal);
+                                                               BKE_nurb_bpoint_calc_plane(nu, bp, plane);
+
+                                                               if (createSpaceNormalTangent(axismtx, normal, plane)) {
+                                                                       /* pass */
+                                                               }
+                                                               else {
+                                                                       normalize_v3(normal);
+                                                                       axis_dominant_v3_to_m3(axismtx, normal);
+                                                                       invert_m3(axismtx);
+                                                               }
+                                                       }
+                                               }
+
                                                copy_v3_v3(td->iloc, bp->vec);
                                                td->loc = bp->vec;
                                                copy_v3_v3(td->center, td->loc);
@@ -1793,6 +1813,11 @@ static void createTransCurveVerts(TransInfo *t)
 
                                                copy_m3_m3(td->smtx, smtx);
                                                copy_m3_m3(td->mtx, mtx);
+                                               if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
+                                                       if (nu->pntsv == 1) {
+                                                               copy_m3_m3(td->axismtx, axismtx);
+                                                       }
+                                               }
 
                                                td++;
                                                count++;
index 23158495b44a220675d3e6944c2b93a859744898..54959304d72086bc9f20406debd98507f992d45d 100644 (file)
@@ -817,15 +817,21 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
                else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
                        Curve *cu = obedit->data;
                        Nurb *nu = NULL;
-                       BezTriple *bezt = NULL;
                        int a;
                        ListBase *nurbs = BKE_curve_editNurbs_get(cu);
 
-                       if (activeOnly && BKE_curve_nurb_vert_active_get(cu, &nu, (void *)&bezt)) {
+                       void *vert_act = NULL;
+                       if (activeOnly && BKE_curve_nurb_vert_active_get(cu, &nu, &vert_act)) {
                                if (nu->type == CU_BEZIER) {
+                                       BezTriple *bezt = vert_act;
                                        BKE_nurb_bezt_calc_normal(nu, bezt, normal);
                                        BKE_nurb_bezt_calc_plane(nu, bezt, plane);
                                }
+                               else {
+                                       BPoint *bp = vert_act;
+                                       BKE_nurb_bpoint_calc_normal(nu, bp, normal);
+                                       BKE_nurb_bpoint_calc_plane(nu, bp, plane);
+                               }
                        }
                        else {
                                const bool use_handle = (cu->drawflag & CU_HIDE_HANDLES) == 0;
@@ -833,7 +839,7 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
                                for (nu = nurbs->first; nu; nu = nu->next) {
                                        /* only bezier has a normal */
                                        if (nu->type == CU_BEZIER) {
-                                               bezt = nu->bezt;
+                                               BezTriple *bezt = nu->bezt;
                                                a = nu->pntsu;
                                                while (a--) {
                                                        short flag = 0;
@@ -885,6 +891,36 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
                                                        bezt++;
                                                }
                                        }
+                                       else if (nu->bp && (nu->pntsv == 1)) {
+                                               BPoint *bp = nu->bp;
+                                               a = nu->pntsu;
+                                               while (a--) {
+                                                       if (bp->f1 & SELECT) {
+                                                               float tvec[3];
+
+                                                               BPoint *bp_prev = BKE_nurb_bpoint_get_prev(nu, bp);
+                                                               BPoint *bp_next = BKE_nurb_bpoint_get_next(nu, bp);
+
+                                                               const bool is_prev_sel = bp_prev && (bp_prev->f1 & SELECT);
+                                                               const bool is_next_sel = bp_next && (bp_next->f1 & SELECT);
+                                                               if (is_prev_sel == false && is_next_sel == false) {
+                                                                       /* Isolated, add based on surrounding */
+                                                                       BKE_nurb_bpoint_calc_normal(nu, bp, tvec);
+                                                                       add_v3_v3(normal, tvec);
+                                                               }
+                                                               else if (is_next_sel) {
+                                                                       /* A segment, add the edge normal */
+                                                                       sub_v3_v3v3(tvec, bp->vec, bp_next->vec );
+                                                                       normalize_v3(tvec);
+                                                                       add_v3_v3(normal, tvec);
+                                                               }
+
+                                                               BKE_nurb_bpoint_calc_plane(nu, bp, tvec);
+                                                               add_v3_v3(plane, tvec);
+                                                       }
+                                                       bp++;
+                                               }
+                                       }
                                }
                        }