Commit: 5d403a6dc3376932967398ac0f8a103e08badbee
Author: João Araújo
Date:   Sat Jul 30 15:41:24 2016 +0100
Branches: gsoc2016-improved_extrusion
https://developer.blender.org/rB5d403a6dc3376932967398ac0f8a103e08badbee

Merge remote-tracking branch 'origin/master' into gsoc2016-improved_extrusion

===================================================================



===================================================================

diff --cc source/blender/editors/curve/editcurve.c
index 482ba72,e40dde2..571bf01
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@@ -6302,1567 -6302,3 +6302,1567 @@@ void CURVE_OT_match_texture_space(wmOpe
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
  }
 +
 +
 +
 +/******************** Extend curve operator ********************/
 +
 +static void get_selected_splines(ListBase* spline_list, ListBase *nubase, int 
*r_number_splines, bool return_cyclic)
 +{
 +      /* receives a list with all Bezier splines in a "curve" object
 +       * returns the first spline of a linked list with all the selected 
splines,
 +       * along with the number of selected splines
 +       * if "return_cyclic" is false, it ignores cyclic splines */
 +
 +      Nurb *nu, *nu_copy;
 +      BezTriple *bezt;
 +      int handles;
 +
 +      for(nu=nubase->first; nu; nu = nu->next)
 +      {
 +              handles = nu->pntsu;
 +              bezt = nu->bezt;
 +              while (handles--)
 +              { /* cycle through all the handles. see if any is selected */
 +                      if (BEZT_ISSEL_ANY(bezt) && (!(nu->flagu & 
CU_NURB_CYCLIC) || return_cyclic))
 +                      { /* this expression was deduced using truth tables */
 +                              *r_number_splines += 1;
 +                              nu_copy = BKE_nurb_duplicate(nu);
 +                              nu_copy->next = NULL;
 +                              nu_copy->prev = NULL;
 +                              BLI_addtail(spline_list, nu_copy);
 +                              break;
 +                      }
 +                      bezt++;
 +              }
 +      }
 +}
 +
 +static ListBase *get_selected_handles(Nurb* nu, int *r_num_sel_handles)
 +{
 +      /* Takes in the first element of a linked list of nurbs
 +       * and returns a ListBase with the BezTriple of the selected handles. */
 +      BezTriple *bezt;
 +      LinkData *link;
 +      ListBase *sel_handles = (ListBase *)MEM_callocN(sizeof(ListBase), 
"get_selected_handles1");
 +      int a;
 +
 +      *r_num_sel_handles = 0;
 +      while (nu) {
 +              a = nu->pntsu;
 +              bezt = nu->bezt;
 +              while (a--) {
 +                      if (BEZT_ISSEL_ANY(bezt)) {
 +                              link = MEM_callocN(sizeof(LinkData), 
"get_selected_handles2");
 +                              link->data = bezt;
 +                              BLI_addtail(sel_handles, link);
 +                              *r_num_sel_handles = *r_num_sel_handles + 1;
 +                      }
 +                      bezt++;
 +              }
 +              nu = nu->next;
 +      }
 +
 +      return sel_handles;
 +}
 +
 +static void get_selected_endpoints(Nurb* nu, BezTriple **r_handle_list)
 +{
 +      /* Takes in a nurb and returns an array with the selected endpoints 
BezTriple */
 +      BezTriple *first_bezt, *last_bezt;
 +      int a;
 +      r_handle_list[0] = r_handle_list[1] = NULL;
 +
 +      a = nu->pntsu - 1;
 +      first_bezt = last_bezt = nu->bezt;
 +
 +      while (a--) {
 +              last_bezt++;
 +      }
 +
 +      if (BEZT_ISSEL_ANY(first_bezt) && BEZT_ISSEL_ANY(last_bezt))
 +      {
 +              r_handle_list[0] = first_bezt;
 +              r_handle_list[1] = last_bezt;
 +      }
 +      else if (BEZT_ISSEL_ANY(first_bezt))
 +      {
 +              r_handle_list[0] = first_bezt;
 +              r_handle_list[1] = NULL;
 +      }
 +      else if (BEZT_ISSEL_ANY(last_bezt))
 +      {
 +              r_handle_list[0] = NULL;
 +              r_handle_list[1] = last_bezt;
 +      }
 +}
 +
 +static void get_nurb_shape_bounds(Object *obedit, float r_bound_box[4])
 +{
 +      /* returns the coordinates of the XY-bounding box of obedit */
 +      r_bound_box[0] = obedit->bb->vec[0][0]; /* min X */
 +      r_bound_box[1] = obedit->bb->vec[4][0]; /* max X */
 +      r_bound_box[2] = obedit->bb->vec[0][1]; /* min Y */
 +      r_bound_box[3] = obedit->bb->vec[3][1]; /* max Y */
 +}
 +
 +static void get_max_extent_2d(float p1[2], float p2[2], float bb[4], float 
r_result[2])
 +{
 +      /* TODO: Find out what this actually does */
 +      if (fabsf(p1[0]-p2[0])) {
 +              if (p1[0] < p2[0]) {
 +                      r_result[0] = bb[0];
 +                      r_result[1] = 
(p2[1]-p1[1])/(p2[0]-p1[0])*(bb[0]-p1[0])+p1[1];
 +              }
 +              else {
 +                      r_result[0] = bb[1];
 +                      r_result[1] = 
(p2[1]-p1[1])/(p2[0]-p1[0])*(bb[1]-p1[0])+p1[1];
 +              }
 +      }
 +      else {
 +              if (p1[1] < p2[1]) {
 +                      r_result[0] = 
(p2[0]-p1[0])/(p2[1]-p1[1])*(bb[2]-p1[1])+p1[0];
 +                      r_result[1] = bb[2];
 +              }
 +              else {
 +                      r_result[0] = 
(p2[0]-p1[0])/(p2[1]-p1[1])*(bb[3]-p1[1])+p1[0];
 +                      r_result[1] = bb[3];
 +              }
 +      }
 +}
 +
 +static void nearest_point(float p[2], ListBase *p_list, float r_near[2], int 
*r_result)
 +{
 +      LinkData *link;
 +      int p_list_size = BLI_listbase_count(p_list);
 +      *r_result = 1;
 +      /* return the point from p_list nearer to p */
 +      if (p_list_size == 0) {
 +              r_near = NULL;
 +              *r_result = 0;
 +      }
 +      else if (p_list_size == 1) {
 +              link = p_list->first;
 +              copy_v2_v2(r_near, link->data);
 +      }
 +      else {
 +              int pos = 0, i = 0;
 +              float distance = len_v2v2(p, ((LinkData 
*)p_list->first)->data), smallest_distance = distance;
 +              for (link = p_list->first; link; link = link->next) {
 +                      distance = len_v2v2(p, link->data);
 +                      if (distance <= smallest_distance) {
 +                              distance = smallest_distance;
 +                              copy_v2_v2(r_near, link->data);
 +                              pos = i;
 +                      }
 +                      i++;
 +              }
 +      }
 +}
 +
 +static ListBase *interpolate_all_segments(Nurb *nu)
 +{
 +      /* return a listbase with all the points in the Bezier curve. Each 
element
 +       * of the ListBase is a segment between two handles.
 +       * If the cuve only has two handles, the final result is only on list
 +       * Otherwise, there is an overlap between the last element of a list and
 +       * the first of the next one */
 +      int i = 0, dims = 3;
 +      float *coord_array;
 +      ListBase *pl = (ListBase *)MEM_callocN(sizeof(ListBase), 
"interpolate_all_segments1");
 +      LinkData *link;
 +
 +      /* number of BezTriples */
 +      int bezier_points = nu->pntsu;
 +
 +      while (i < bezier_points-1+nu->flagu) {
 +              coord_array = MEM_callocN(dims * (nu->resolu + 1) * 
sizeof(float), "interpolate_all_segments2");
 +              link = MEM_callocN(sizeof(LinkData), 
"interpolate_all_segments3");
 +              link->data = coord_array;
 +              for (int j = 0; j < dims; j++) {
 +                      
BKE_curve_forward_diff_bezier(nu->bezt[i%bezier_points].vec[1][j],
 +                                                                              
  nu->bezt[i%bezier_points].vec[2][j],
 +                                                                              
  nu->bezt[(i+1)%bezier_points].vec[0][j],
 +                                                                              
  nu->bezt[(i+1)%bezier_points].vec[1][j],
 +                                                                              
  coord_array + j, nu->resolu, sizeof(float) * dims);
 +              }
 +              BLI_addtail(pl, link);
 +              i++;
 +      }
 +
 +      return pl;
 +}
 +
 +static void linear_spline_list(ListBase *nubase, ListBase *spline_list)
 +{
 +      /* return a list with all the points of a curve object */
 +      LinkData *link;
 +      Nurb *nu;
 +
 +      for (nu=nubase->first; nu; nu=nu->next) {
 +              link = MEM_callocN(sizeof(LinkData), "linearspllist1");
 +              link->data = interpolate_all_segments(nu);
 +              BLI_addtail(spline_list, link);
 +      }
 +}
 +
 +static void get_intersections(ListBase* il, float *p1, float *p2, ListBase 
*nubase)
 +{
 +      /* return a list with all the intersection points of the segment p1p2 
with the curve object */
 +      ListBase spline_list = {NULL}, *points_list;
 +      LinkData *intersection, *link, *spl;
 +      float *coord_array, *vi, p3[2], p4[2];
 +      Nurb *nu = nubase->first;
 +      int dims = 3, result;
 +      const float PRECISION = 1e-05;
 +
 +      linear_spline_list(nubase, &spline_list);               /* all the 
points in a curve object */
 +      for (spl=spline_list.first; spl; spl=spl->next) { /* selecting the 
points of a given spline */
 +              points_list = spl->data;        /* output of 
interpolate_all_segments */
 +              for (link = points_list->first; link; link=link->next) {
 +                      coord_array = (float *)link->data;
 +                      for (int i = 0; i < nu->resolu; i++) {
 +                              vi = (float *) MEM_callocN(3 * sizeof(float), 
"get_intersections2");
 +                              p3[0] = coord_array[i * dims];
 +                              p3[1] = coord_array[i * dims + 1];
 +                              p4[0] = coord_array[(i + 1) * dims];
 +                              p4[1] = coord_array[(i + 1) * dims + 1];
 +                              result = isect_seg_seg_v2_point(p2, p1, p3, p4, 
vi);
 +                              if (result == 1 && len_v2v2(vi, p1) > 
PRECISION) {
 +                                      /* a hit, lets add it. */
 +                                      intersection = 
MEM_callocN(sizeof(LinkData), "get_intersections4");
 +                                      intersection->data = vi;
 +                                      BLI_addtail(il, intersection);
 +                              }
 +                              else {
 +                                      /* not going to add, so free the memory 
we reserved, not used. */
 +                                      MEM_freeN(vi);
 +                              }
 +                      }
 +                      MEM_freeN(link->data);   /* commenting either does not 
free the memory */
 +                      MEM_freeN(coord_array);  /* running both gives an 
error, but seems to free the memory */
 +              }
 +              BLI_freelistN(spl->data);
 +              BLI_freelistN(points_list);
 +              MEM_freeN(points_list);
 +      }
 +      BLI_freelistN(&spline_list);
 +      MEM_freeN(&spline_list);
 +}
 +
 +static int extend_curve_exec(bContext *C, wmOperator *op)
 +{
 +      Object *obedit = CTX_data_edit_object(C);
 +      Nurb *first_spline, *second_spline;
 +      Curve *cu = obedit->data;
 +      Nurb *nu;
 +      EditNurb *editnurb = cu->editnurb;
 +      ListBase spline_list = {NULL};
 +      ListBase intersections_list = {NULL};
 +      ListBase *nubase = object_editcurve_get(obedit);
 +      BezTriple **selected_endpoints = NULL, **first_selected_endpoints = 
NULL, **second_selected_endpoints = NULL, *bezt;
 +      int n_selected_splines = 0, result = 0, a = 0;
 +      float p1[3], p2[3] = {0.0, 0.0, 0.0}, p1_handle[3], bound_box[4], 
p1_extend[2];
 +
 +      for (nu = nubase->first; nu; nu = nu->next)
 +      {
 +              if (!(nu->type & CU_BEZIER))
 +              {
 +                      BKE_report(op->reports, RPT_ERROR, "Only Bezier curves 
can be extended");
 +                      return OPERATOR_CANCELLED;
 +              }
 +      }
 +
 +      get_selected_splines(&spline_list, nubase, &n_selected_splines, false);
 +
 +      /* the user can only select one or two splines */
 +      if ((n_selected_splines == 0 || n_selected_splines > 2)) {
 +              BKE_report(op->reports, RPT_ERROR, "Cannot extend current 
selection");
 +              return OPERATOR_CANCELLED;
 +      }
 +
 +      first_spline = (Nurb *)spline_list.first;
 +      second_spline = (Nurb *)spline_list.last;
 +
 +      if (n_selected_splines == 1) { /* one spline selected */
 +              selected_endpoints = MEM_callocN(2 * sizeof(BezTriple*), 
"extendcurve1");
 +              get_selected_endpoints(first_spline, selected_endpoints);
 +
 +              if (selected_endpoints[0] && selected_endpoints[1]) { /* both 
endpoints are selected */
 +                      result = 
isect_line_line_v3(selected_endpoints[0]->vec[1], selected_endpoints[0]->vec[0],
 +                                                                              
selected_endpoints[1]->vec[1], selected_endpoints[1]->vec[2],
 +                                                                              
p1, p2); /* result serves to check the existence of the intersection;
 +                                                                              
                  * the intersection point is on variables p1 and p2 */
 +              }
 +              else if (selected_endpoints[0] || selected_endpoints[1]) { /* 
only one endpoint selected */
 +                      if (selected_endpoints[0])
 +                      {
 +                              copy_v3_v3(p1, selected_endpoints[0]->vec[1]);
 +                              copy_v3_v3(p1_handle

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to