/**
 * This is the main routine of "MonoCrosser", and implements a monotonic strategy on multiple curves.
 * Finds crossings between two sets of paths, yielding a CrossingSet.  [0, a.size()) of the return correspond
 * to the sorted crossings of a with paths of b.  The rest of the return, [a.size(), a.size() + b.size()],
 * corresponds to the sorted crossings of b with paths of a.
 *
 * This function does two sweeps, one on the bounds of each path, and after that cull, one on the curves within.
 * This leads to a certain amount of code complexity, however, most of that is factored into the above functions
 */
CrossingSet MonoCrosser::crossings(std::vector<Path> const &a, std::vector<Path> const &b) {
    if(b.empty()) return CrossingSet(a.size(), Crossings());
    CrossingSet results(a.size() + b.size(), Crossings());
    if(a.empty()) return results;
    
    std::vector<std::vector<double> > splits_a = paths_mono_splits(a), splits_b = paths_mono_splits(b);
    std::vector<std::vector<Rect> > bounds_a = split_bounds(a, splits_a), bounds_b = split_bounds(b, splits_b);
    
    std::vector<Rect> bounds_a_union, bounds_b_union; 
    for(unsigned i = 0; i < bounds_a.size(); i++) bounds_a_union.push_back(union_list(bounds_a[i]));
    for(unsigned i = 0; i < bounds_b.size(); i++) bounds_b_union.push_back(union_list(bounds_b[i]));
    
    std::vector<std::vector<unsigned> > cull = sweep_bounds(bounds_a_union, bounds_b_union);
    Crossings n;
    for(unsigned i = 0; i < cull.size(); i++) {
        for(unsigned jx = 0; jx < cull[i].size(); jx++) {
            unsigned j = cull[i][jx];
            unsigned jc = j + a.size();
            Crossings res;
            
            //Sweep of the monotonic portions
            std::vector<std::vector<unsigned> > cull2 = sweep_bounds(bounds_a[i], bounds_b[j]);
            for(unsigned k = 0; k < cull2.size(); k++) {
                for(unsigned lx = 0; lx < cull2[k].size(); lx++) {
                    unsigned l = cull2[k][lx];
                    mono_pair(a[i], splits_a[i][k-1], splits_a[i][k],
                              b[j], splits_b[j][l-1], splits_b[j][l],
                              res, .1);
                }
            }
            
            for(unsigned k = 0; k < res.size(); k++) { res[k].a = i; res[k].b = jc; }
            
            merge_crossings(results[i], res, i);
            merge_crossings(results[i], res, jc);
        }
    }

    return results;
}
Exemple #2
0
bool my_walker(Node *node, context_walker_set_constraint *context){
  if (node == NULL)
 			return false;

  /* elog(LOG,"tag : %d\n",nodeTag(node)); */

  if(IsA(node,BoolExpr)){
    BoolExpr * bExpr =(BoolExpr *) node;
    bool retour = false;
    List * l_true_save = NULL;
    List * l_false_save = NULL;
    List * l_true = NULL;
    List * l_false = NULL;
    int nb_arg = bExpr->args->length;
    switch(bExpr->boolop){
      case NOT_EXPR:
        /*(Unicité des valeur) Setisation sur le true*/
        /*Pre Traitement*/
        l_true_save = context->list_of_not_null_to_be_true;
        l_false_save = context->list_of_not_null_to_be_false;
        context->list_of_not_null_to_be_true = NULL;
        context->list_of_not_null_to_be_false = NULL;

        /*Traitement*/
        retour = expression_tree_walker(node, my_walker, (void *) context);

        /*Post Traitement*/
        /* elog(LOG,"\n List_false_before : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */
        /* elog(LOG,"\n List_true_before : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */
        l_true = context->list_of_not_null_to_be_true;
        l_false = context->list_of_not_null_to_be_false;
        context->list_of_not_null_to_be_true = list_concat(l_true_save,l_false);
        context->list_of_not_null_to_be_false = list_concat(l_false_save,l_true);
        /* elog(LOG,"\n List_false : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */
        /* elog(LOG,"\n List_true : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */

        return retour;

        break;
      case AND_EXPR:
        /*(Unicité des valeur) Setisation sur le true*/
        /*Pre Traitement*/
        l_true_save = context->list_of_not_null_to_be_true;
        l_false_save = context->list_of_not_null_to_be_false;
        context->list_of_not_null_to_be_true = NULL;
        context->list_of_not_null_to_be_false = NULL;

        /*Traitement*/
        retour = expression_tree_walker(node, my_walker, (void *) context);

        /*Post traitement*/
        /* elog(LOG,"\n List_false_before : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */
        /* elog(LOG,"\n List_true_before : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */

        l_true = union_list(context->list_of_not_null_to_be_true);
        l_false = inter_list(context->list_of_not_null_to_be_false,nb_arg);
        context->list_list_true = lappend(context->list_list_true,l_true);
        context->list_list_false = lappend(context->list_list_false,l_false);
        context->list_of_not_null_to_be_true = list_concat(l_true_save,l_true);
        context->list_of_not_null_to_be_false = list_concat(l_false_save,l_false);

        /* elog(LOG,"\n nb_arg : %d\n",nb_arg); */
        /* elog(LOG,"\n List_false : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */
        /* elog(LOG,"\n List_true : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */
        return retour;

        break;
      case OR_EXPR:
        /*(Unicité des valeur) Setisation sur le true*/
        /*Pre Traitement*/
        l_true_save = context->list_of_not_null_to_be_true;
        l_false_save = context->list_of_not_null_to_be_false;
        context->list_of_not_null_to_be_true = NULL;
        context->list_of_not_null_to_be_false = NULL;

        /*Traitement*/
        retour = expression_tree_walker(node, my_walker, (void *) context);

        /*Post traitement*/
        /* elog(LOG,"\n List_false_before : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */
        /* elog(LOG,"\n List_true_before : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */


        l_true = inter_list(context->list_of_not_null_to_be_true,nb_arg);
        l_false = union_list(context->list_of_not_null_to_be_false);
        context->list_list_true = lappend(context->list_list_true,l_true);
        context->list_list_false = lappend(context->list_list_false,l_false);
        context->list_of_not_null_to_be_true = list_concat(l_true_save,l_true);
        context->list_of_not_null_to_be_false = list_concat(l_false_save,l_false);

        /* elog(LOG,"\n nb_arg : %d\n",nb_arg); */
        /* elog(LOG,"\n List_false : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */
        /* elog(LOG,"\n List_true : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */

        return retour;

        break;
    }

  }

  if(context->ready && IsA(node,Var)){
    /* elog(LOG," \n HERE1 \n"); */
    Var * v = getTrueVar(context->current_trueVar,(Var *)node);
    /* elog(LOG," \n HERE2 \n"); */
    if(!isInListTrueVar(context->list_of_not_null_in_op,v)){
      context->list_of_not_null_in_op = lappend(context->list_of_not_null_in_op,v);
    }
    return expression_tree_walker(node, my_walker, (void *) context);
  }

  if(IsA(node,OpExpr)){
     OpExpr * oExpr = (OpExpr *)node;
     if(oExpr->opno == 518 /*<>*/){
        context->ready = true;
        context->list_of_not_null_in_op = NULL;
        bool retour = expression_tree_walker(node, my_walker, (void *) context);
        context->list_of_not_null_to_be_true = list_concat(context->list_of_not_null_to_be_true,context->list_of_not_null_in_op);
        return retour;
     }
     else{
       return expression_tree_walker(node, my_walker, (void *) context);
     }
     /* elog(LOG,"\n List_op : %s\n",nodeToString(context->list_of_not_null_in_op)); */
  }

  if(IsA(node,Query)){
    Query * q = (Query *) node;
    
    /*Prétraitement*/
    List * save_current_trueVar = context->current_trueVar;
    context->current_trueVar = NULL;
    context->current_trueVar = lappend(context->current_trueVar,save_current_trueVar);
    
    /*Traitement*/
    /*Create trueVars and not_null schema*/
    bool result =  expression_tree_walker((Node *)q->rtable, my_walker, (void *) context);
    /* elog(LOG,"\n TRUE ATT :%s\n",nodeToString(context->trueVars)); */
    context->trueVars = lappend(context->trueVars,context->current_trueVar);
    /* elog(LOG,"\nTRUE ATT :%s \n",nodeToString(context->trueVars)); */
    /*Propagate*/
    result = expression_tree_walker((Node *)q->jointree, my_walker, (void *) context) | result;
    /* elog(LOG,"\n LIST_LIST_TRUE :%s\n",nodeToString(context->list_list_true)); */
    /* elog(LOG,"\n LIST_LIST_FALSE :%s\n",nodeToString(context->list_list_false)); */

    /*Post Traitement*/
    context->current_trueVar = save_current_trueVar;
    return result;
  }
  if(IsA(node,RangeTblEntry)){
    RangeTblEntry * rte = (RangeTblEntry *)node;
    Oid relid= rte->relid;
    int number_col = get_relnatts(relid);
    AttrNumber i = 0;
    List * relation = NULL;
    for(i=1;i<=number_col;i++){
      /*Create True_var*/
      Var * v = makeNode(Var);
      v->varattno = i;
      /* v->varattno = context->current_varattno; */
      v->vartype = relid;
      relation =  lappend(relation,v);
      /*Add to not_null if needed*/
      if(get_pg_att_not_null(relid,i)){
        context->list_of_not_null_att_schem = lappend(context->list_of_not_null_att_schem,v);
      }
    }
    context->current_trueVar = lappend(context->current_trueVar,relation);
    /* elog(LOG,"\n TEST: %s \n",nodeToString(context->current_trueVar)); */
    return false;
  }
  return expression_tree_walker(node, my_walker, (void *) context);
}