Revision: 64375
          http://sourceforge.net/p/brlcad/code/64375
Author:   starseeker
Date:     2015-03-12 15:23:00 +0000 (Thu, 12 Mar 2015)
Log Message:
-----------
Preparing logic for boolean building that incorporates an intersection test 
phase.

Modified Paths:
--------------
    brlcad/trunk/src/libbrep/shape_recognition.cpp
    brlcad/trunk/src/libbrep/shape_recognition.h
    brlcad/trunk/src/libbrep/shape_recognition_cone.cpp
    brlcad/trunk/src/libbrep/shape_recognition_cylinder.cpp
    brlcad/trunk/src/libbrep/shape_recognition_sphere.cpp
    brlcad/trunk/src/libbrep/shape_recognition_util.cpp
    brlcad/trunk/src/librt/test_shape_recognition.cpp

Modified: brlcad/trunk/src/libbrep/shape_recognition.cpp
===================================================================
--- brlcad/trunk/src/libbrep/shape_recognition.cpp      2015-03-12 01:50:28 UTC 
(rev 64374)
+++ brlcad/trunk/src/libbrep/shape_recognition.cpp      2015-03-12 15:23:00 UTC 
(rev 64375)
@@ -108,7 +108,7 @@
            // by the edge network.
            new_obj->is_island = 1;
            new_obj->parent = NULL;
-
+#if 0
            // Determine if this subset is being added to or taken from the 
parent.
            if (new_obj->fil_cnt > 0) {
                int bool_op = subbrep_determine_boolean(new_obj);
@@ -124,7 +124,7 @@
            } else {
                new_obj->params->bool_op = 'u';
            }
-
+#endif
            surface_t hof = highest_order_face(new_obj);
            if (hof >= SURFACE_GENERAL) {
                new_obj->type = BREP;
@@ -155,22 +155,6 @@
     return subbreps;
 }
 
-
-// assistant function for find_top_level_hierarchy
-void
-subbrep_assemble_boolean_tree(std::multimap<const char *, long *> *ps, struct 
bu_ptbl *subbreps_tree, const struct subbrep_object_data *obj)
-{
-    std::pair <std::multimap<const char *, long *>::iterator, 
std::multimap<const char *, long *>::iterator > ret;
-    ret = ps->equal_range(bu_vls_addr(obj->key));
-    for (std::multimap<const char *, long *>::iterator it = ret.first; it != 
ret.second; it++) {
-       const struct subbrep_object_data *sub_obj = (const struct 
subbrep_object_data *)it->second;
-       if (sub_obj) {
-           bu_ptbl_ins(subbreps_tree, (long *)sub_obj);
-           subbrep_assemble_boolean_tree(ps, subbreps_tree, sub_obj);
-       }
-    }
-}
-
 /* This is the critical point at which we take a pile of shapes and actually 
reconstruct a
  * valid boolean tree.  The stages are as follows:
  *
@@ -205,14 +189,13 @@
 
     std::set<long *> subbrep_set;
     std::set<long *> subbrep_seed_set;
-    std::set<long *> toplevel_unions;
+    std::set<long *> unions;
+    std::set<long *> subtractions;
     std::set<long *>::iterator sb_it, sb_it2;
     std::map<long *, std::set<long *> > subbrep_subobjs;
+    std::map<long *, std::set<long *> > subbrep_ignoreobjs;
     struct bu_ptbl *subbreps_tree;
-    BU_GET(subbreps_tree, struct bu_ptbl);
-    bu_ptbl_init(subbreps_tree, 8, "subbrep tree table");
 
-    std::multimap<const char *, long *> ps;
     for (unsigned int i = 0; i < BU_PTBL_LEN(subbreps); i++) {
        subbrep_set.insert(BU_PTBL_GET(subbreps, i));
     }
@@ -221,17 +204,18 @@
     for (sb_it = subbrep_set.begin(); sb_it != subbrep_set.end(); sb_it++) {
        struct subbrep_object_data *obj = (struct subbrep_object_data *)*sb_it;
        if (obj->fil_cnt == 0) {
-           std::cout << "Top union found: " << bu_vls_addr(obj->key) << "\n";
-           toplevel_unions.insert((long *)obj);
+           //std::cout << "Top union found: " << bu_vls_addr(obj->key) << "\n";
+           obj->params->bool_op = 'u';
+           unions.insert((long *)obj);
            subbrep_set.erase((long *)obj);
        }
     }
 
-    subbrep_seed_set = toplevel_unions;
+    subbrep_seed_set = unions;
 
     int iterate = 1;
     while (subbrep_seed_set.size() > 0) {
-       std::cout << "iterate: " << iterate << "\n";
+       //std::cout << "iterate: " << iterate << "\n";
        std::set<long *> subbrep_seed_set_2;
        std::set<long *> subbrep_set_b;
        for (sb_it = subbrep_seed_set.begin(); sb_it != subbrep_seed_set.end(); 
sb_it++) {
@@ -243,13 +227,96 @@
                struct subbrep_object_data *cobj = (struct subbrep_object_data 
*)*sb_it2;
                for (int i = 0; i < cobj->fil_cnt; i++) {
                    if (tu_fol.find(cobj->fil[i]) != tu_fol.end()) {
-                       std::cout << "Object " << bu_vls_addr(cobj->key) << " 
connected to " << bu_vls_addr(tu->key) << "\n";
-                       subbrep_subobjs[*sb_it].insert(*sb_it2);
+                       struct subbrep_object_data *up;
+                       //std::cout << "Object " << bu_vls_addr(cobj->key) << " 
connected to " << bu_vls_addr(tu->key) << "\n";
                        subbrep_seed_set_2.insert(*sb_it2);
                        subbrep_set_b.erase(*sb_it2);
-                       // TODO - determine boolean relationship to parent 
here, and use parent boolean
+                       // Determine boolean relationship to parent here, and 
use parent boolean
                        // to decide this object's (cobj) status.  If tu is 
negative and cobj is unioned
                        // relative to tu, then cobj is also negative.
+
+                       // This is a make-or-break step of the algorithm - if 
we cannot determine whether
+                       // a subbrep is added or subtracted, the whole B-Rep 
conversion process fails.
+                       //
+                       // TODO - In theory a partial convertion might still be 
achieved by re-inserting the
+                       // problem subbrep back into the parent B-Rep and 
proceeding with the rest, but
+                       // we are not currently set up for that - as of right 
now, a single failure on
+                       // this level of logic results in a completely failed 
csg conversion.
+
+                       int bool_test = 0;
+                       int already_flipped = 0;
+                       if (cobj->params->bool_op == '\0') {
+                           /* First, check the boolean relationship to the 
parent solid */
+                           cobj->parent = tu;
+                           bool_test = subbrep_determine_boolean(cobj);
+                           //std::cout << "Initial boolean test for " << 
bu_vls_addr(cobj->key) << ": " << bool_test << "\n";
+                           switch (bool_test) {
+                               case -2:
+                                   std::cout << "Game over - self intersecting 
shape reported with subbrep " << bu_vls_addr(cobj->key) << ".\n";
+                                   std::cout << "Until breakdown logic for 
this situation is available, this is a conversion stopper.\n";
+                                   return NULL;
+                               case -1:
+                                   /* Determination made relative to parent 
shape - take parent status into account */
+                                   if (cobj->parent->params->bool_op == '-') 
bool_test = -1 * bool_test;
+                               case 1:
+                                   /* Determination made relative to parent 
shape - take parent status into account */
+                                   if (cobj->parent->params->bool_op == '-') 
bool_test = -1 * bool_test;
+                                   break;
+                               case 2:
+                                   /* Test relative to parent inconclusive - 
fall back on surface test, if available */
+                                   if (cobj->negative_shape == -1) bool_test = 
-1;
+                                   if (cobj->negative_shape == 1) bool_test = 
1;
+                           }
+                       } else {
+                           //std::cout << "Boolean status of " << 
bu_vls_addr(cobj->key) << " already determined\n";
+                           bool_test = (cobj->params->bool_op == '-') ? -1 : 1;
+                           already_flipped = 1;
+                       }
+
+                       switch (bool_test) {
+                           case -1:
+                               cobj->params->bool_op = '-';
+                               subtractions.insert((long *)cobj);
+                               subbrep_subobjs[*sb_it].insert((long *)cobj);
+                               break;
+                           case 1:
+                               cobj->params->bool_op = 'u';
+                               unions.insert((long *)cobj);
+                               /* We've got a union - any subtractions that 
are parents of this
+                                * object go in its ignore list */
+                               up = cobj->parent;
+                               while (up) {
+                                   if (up->params->bool_op == '-') 
subbrep_ignoreobjs[(long *)cobj].insert((long *)up);
+                                   up = up->parent;
+                               }
+                               break;
+                           default:
+                               std::cout << "Boolean status of " << 
bu_vls_addr(cobj->key) << " could not be determined - conversion failure\n";
+                               return NULL;
+                               break;
+                       }
+
+                       // If the parent ended up subtracted, we need to 
propagate the change down the
+                       // children of this subbrep.
+                       if (bool_test == -1 && !already_flipped) {
+                           for (unsigned int j = 0; j < 
BU_PTBL_LEN(cobj->children); j++){
+                               struct subbrep_object_data *cdata = (struct 
subbrep_object_data *)BU_PTBL_GET(cobj->children,j);
+                               if (cdata && cdata->params) {
+                                   cdata->params->bool_op = 
(cdata->params->bool_op == '-') ? 'u' : '-';
+                               } else {
+                                   std::cout << "Child without params??: " << 
bu_vls_addr(cdata->key) << ", parent: " << bu_vls_addr(cobj->key) << "\n";
+                               }
+                           }
+
+                           /* If we're a B-Rep and a subtraction, the B-Rep 
will be inside out */
+                           if (cobj->type == BREP && cobj->params->bool_op == 
'-') {
+                               for (int l = 0; l < 
cobj->local_brep->m_F.Count(); l++) {
+                                   ON_BrepFace &face = 
cobj->local_brep->m_F[l];
+                                   cobj->local_brep->FlipFace(face);
+                               }
+                           }
+                       }
+                       //std::cout << "Boolean status of " << 
bu_vls_addr(cobj->key) << ": " << cobj->params->bool_op << "\n";
                    }
                }
            }
@@ -261,37 +328,27 @@
        iterate++;
     }
 
-#if 0
-       if (obj->params->bool_op == '-') {
-           int found_parent = 0;
-           for (unsigned int j = 0; j < BU_PTBL_LEN(subbreps); j++) {
-               struct subbrep_object_data *pobj = (struct subbrep_object_data 
*)BU_PTBL_GET(subbreps, j);
-               for (int k = 0; k < obj->fil_cnt; k++) {
-                   for (int l = 0; l < pobj->fol_cnt; l++) {
-                       if (pobj->fol[l] == obj->fil[k]) {
-                           found_parent = 1;
-                           ps.insert(std::make_pair(bu_vls_addr(pobj->key), 
(long *)obj));
-                           break;
-                       }
-                       if (found_parent) break;
-                   }
-                   if (found_parent) break;
-               }
-               if (found_parent) break;
-           }
-           if (!found_parent) {
-               std::cout << "\n\nError - subtracted object " << 
bu_vls_addr(obj->key) << "\n\n\n";
-           }
+    BU_GET(subbreps_tree, struct bu_ptbl);
+    bu_ptbl_init(subbreps_tree, 8, "subbrep tree table");
+
+    for (sb_it = unions.begin(); sb_it != unions.end(); sb_it++) {
+       struct subbrep_object_data *pobj = (struct subbrep_object_data 
*)(*sb_it);
+       bu_ptbl_ins(subbreps_tree, (long *)pobj);
+       std::set<long *> topological_subtractions = subbrep_subobjs[(long 
*)pobj];
+       std::set<long *> local_subtraction_queue = subtractions;
+       for (sb_it2 = topological_subtractions.begin(); sb_it2 != 
topological_subtractions.end(); sb_it2++) {
+           bu_ptbl_ins(subbreps_tree, *sb_it2);
+           local_subtraction_queue.erase(*sb_it2);
        }
-    }
-   for (unsigned int i = 0; i < BU_PTBL_LEN(subbreps); i++) {
-       struct subbrep_object_data *obj = (struct subbrep_object_data 
*)BU_PTBL_GET(subbreps, i);
-       if (obj->params->bool_op == 'u') {
-           bu_ptbl_ins(subbreps_tree, (long *)obj);
-           subbrep_assemble_boolean_tree(&ps, subbreps_tree, obj);
+       std::set<long *> ignore_queue = subbrep_ignoreobjs[(long *)pobj];
+       for (sb_it2 = ignore_queue.begin(); sb_it2 != ignore_queue.end(); 
sb_it2++) {
+           local_subtraction_queue.erase(*sb_it2);
        }
+       // Now, whatever is left in the local subtraction queue has to be ruled 
out based on volumetric
+       // intersection testing.
+       //
+       // TODO - bounding box fun.
     }
-#endif
     return subbreps_tree;
 }
 
@@ -779,15 +836,6 @@
     data->local_brep->ShrinkSurfaces();
     data->local_brep->CullUnusedSurfaces();
 
-    /* If we're a subtraction, the B-Rep will be inside out */
-    if (data->params->bool_op == '-') {
-       for (int l = 0; l < data->local_brep->m_F.Count(); l++) {
-           ON_BrepFace &face = data->local_brep->m_F[l];
-           data->local_brep->FlipFace(face);
-       }
-    }
-
-
     std::cout << "new brep done: " << bu_vls_addr(data->key) << "\n";
 
     return 1;

Modified: brlcad/trunk/src/libbrep/shape_recognition.h
===================================================================
--- brlcad/trunk/src/libbrep/shape_recognition.h        2015-03-12 01:50:28 UTC 
(rev 64374)
+++ brlcad/trunk/src/libbrep/shape_recognition.h        2015-03-12 15:23:00 UTC 
(rev 64375)
@@ -117,6 +117,15 @@
     subbrep_object_data *parent;
     struct bu_ptbl *children;
     int is_island;
+    /* Irrespective of the broader context, is the shape
+     * itself negative?  This is not meaningful for general
+     * combs, but individual shapes like cylinders and spheres
+     * (even when they are "trimmed down" by other CSG primitives
+     * are "negative" if their normals point inward.
+     * -1 = negative
+     *  1 = positive
+     *  0 = unknown/unset */
+    int negative_shape;
 };
 
 void subbrep_object_init(struct subbrep_object_data *obj, const ON_Brep *brep);

Modified: brlcad/trunk/src/libbrep/shape_recognition_cone.cpp
===================================================================
--- brlcad/trunk/src/libbrep/shape_recognition_cone.cpp 2015-03-12 01:50:28 UTC 
(rev 64374)
+++ brlcad/trunk/src/libbrep/shape_recognition_cone.cpp 2015-03-12 15:23:00 UTC 
(rev 64375)
@@ -142,23 +142,9 @@
 
     ON_3dVector hvect(cone.ApexPoint() - cone.BasePoint());
 
-    int negative = negative_cone(data, *conic_surfaces.begin(), cone_tol);
+    data->negative_shape = negative_cone(data, *conic_surfaces.begin(), 
cone_tol);
 
-    if (data->parent->params->bool_op == '-') negative = -1 * negative;
-
-    switch (negative) {
-       case -1:
-           data->params->bool_op = '-';
-           break;
-       case 1:
-           data->params->bool_op = 'u';
-           break;
-       default:
-           std::cout << "Could not determine cone status???????\n";
-           data->params->bool_op = 'u';
-           break;
-    }
-
+    data->params->bool_op = (data->negative_shape == -1) ? '-' : 'u';
     data->params->origin[0] = cone.BasePoint().x;
     data->params->origin[1] = cone.BasePoint().y;
     data->params->origin[2] = cone.BasePoint().z;
@@ -268,23 +254,9 @@
        struct csg_object_params * obj;
         BU_GET(obj, struct csg_object_params);
 
-       int negative = negative_cone(data, *conic_surfaces.begin(), cone_tol);
+       data->negative_shape = negative_cone(data, *conic_surfaces.begin(), 
cone_tol);
 
-       if (data->parent->params->bool_op == '-') negative = -1 * negative;
-
-       switch (negative) {
-           case -1:
-               data->params->bool_op = '-';
-               break;
-           case 1:
-               data->params->bool_op = 'u';
-               break;
-           default:
-               std::cout << "Could not determine cone status???????\n";
-               data->params->bool_op = 'u';
-               break;
-       }
-
+       data->params->bool_op = (data->negative_shape == -1) ? '-' : 'u';
        data->params->origin[0] = closest_to_base.x;
        data->params->origin[1] = closest_to_base.y;
        data->params->origin[2] = closest_to_base.z;
@@ -318,22 +290,9 @@
            BU_GET(obj, struct csg_object_params);
            data->type = CONE;
 
-           int negative = negative_cone(data, *conic_surfaces.begin(), 
cone_tol);
+           data->negative_shape = negative_cone(data, *conic_surfaces.begin(), 
cone_tol);
 
-           if (data->parent->params->bool_op == '-') negative = -1 * negative;
-
-           switch (negative) {
-               case -1:
-                   data->params->bool_op = '-';
-                   break;
-               case 1:
-                   data->params->bool_op = 'u';
-                   break;
-               default:
-                   data->params->bool_op = 'u';
-                   break;
-           }
-
+           data->params->bool_op = (data->negative_shape == -1) ? '-' : 'u';
            data->params->origin[0] = base.x;
            data->params->origin[1] = base.y;
            data->params->origin[2] = base.z;
@@ -349,23 +308,9 @@
        } else {
            // Have corners, need arb
            data->type = COMB;
-           int negative = negative_cone(data, *conic_surfaces.begin(), 
cone_tol);
+           data->negative_shape = negative_cone(data, *conic_surfaces.begin(), 
cone_tol);
+           data->params->bool_op = (data->negative_shape == -1) ? '-' : 'u';
 
-           if (data->parent->params->bool_op == '-') negative = -1 * negative;
-
-           switch (negative) {
-               case -1:
-                   data->params->bool_op = '-';
-                   break;
-               case 1:
-                   data->params->bool_op = 'u';
-                   break;
-               default:
-                   std::cout << "Could not determine cone status???????\n";
-                   data->params->bool_op = 'u';
-                   break;
-           }
-
            struct subbrep_object_data *cone_obj;
            BU_GET(cone_obj, struct subbrep_object_data);
            subbrep_object_init(cone_obj, data->brep);
@@ -505,7 +450,7 @@
                     vert_loop.Append(v2);
                     vert_loop.Append(v3);
                     vert_loop.Append(v4);
-                    subbrep_add_planar_face(data->parent, &pcone, &vert_loop, 
negative);
+                    subbrep_add_planar_face(data->parent, &pcone, &vert_loop, 
data->negative_shape);
                 }
             }
 

Modified: brlcad/trunk/src/libbrep/shape_recognition_cylinder.cpp
===================================================================
--- brlcad/trunk/src/libbrep/shape_recognition_cylinder.cpp     2015-03-12 
01:50:28 UTC (rev 64374)
+++ brlcad/trunk/src/libbrep/shape_recognition_cylinder.cpp     2015-03-12 
15:23:00 UTC (rev 64375)
@@ -198,18 +198,9 @@
     // cylinder surface.  Whether it is actually subtracted from the
     // global object or unioned into a comb lower down the tree (or vice versa)
     // is determined later.
-    int negative = negative_cylinder(data, *cylindrical_surfaces.begin(), 
cyl_tol);
+    data->negative_shape = negative_cylinder(data, 
*cylindrical_surfaces.begin(), cyl_tol);
 
-    //bu_log("full cylinder negative test: %d\n", negative);
-    // TODO - the surface negative test may not be enough on its own - needs
-    // more thought
-    if (negative == -1) {
-       data->params->bool_op = '-';
-    }
-    if (negative == 1) {
-       data->params->bool_op = 'u';
-    }
-
+    data->params->bool_op = (data->negative_shape == -1) ? '-' : 'u';
     data->params->origin[0] = set1_c.Center().x;
     data->params->origin[1] = set1_c.Center().y;
     data->params->origin[2] = set1_c.Center().z;
@@ -466,28 +457,14 @@
        // cylinder surface.  Whether the comb is actually subtracted from the
        // global object or unioned into a comb lower down the tree (or vice 
versa)
        // is determined later.
-       int negative = negative_cylinder(data, *cylindrical_surfaces.begin(), 
cyl_tol);
+       data->negative_shape = negative_cylinder(data, 
*cylindrical_surfaces.begin(), cyl_tol);
+       data->params->bool_op = (data->negative_shape == -1) ? '-' : 'u';
 
 
        if (corner_verts.size() == 0) {
            //std::cout << "Full cylinder\n";
            data->type = CYLINDER;
 
-           if (data->parent->params->bool_op == '-') negative = -1 * negative;
-
-           switch (negative) {
-               case -1:
-                   data->params->bool_op = '-';
-                   break;
-               case 1:
-                   data->params->bool_op = 'u';
-                   break;
-               default:
-                   std::cout << "Could not determine cylinder status???????\n";
-                   data->params->bool_op = 'u';
-                   break;
-           }
-
            data->params->origin[0] = set1_c.Center().x;
            data->params->origin[1] = set1_c.Center().y;
            data->params->origin[2] = set1_c.Center().z;
@@ -515,21 +492,6 @@
            bu_vls_sprintf(cyl_obj->key, "%s", key.c_str());
            cyl_obj->type = CYLINDER;
 
-           if (data->parent->params->bool_op == '-') negative = -1 * negative;
-
-           switch (negative) {
-               case -1:
-                   data->params->bool_op = '-';
-                   break;
-               case 1:
-                   data->params->bool_op = 'u';
-                   break;
-               default:
-                   std::cout << "Could not determine cylinder status???????\n";
-                   data->params->bool_op = 'u';
-                   break;
-           }
-
            // cylinder - positive object in this sub-comb
            cyl_obj->params->bool_op = 'u';
            cyl_obj->params->origin[0] = set1_c.Center().x;
@@ -661,7 +623,7 @@
                    vert_loop.Append(v2);
                    vert_loop.Append(v3);
                    vert_loop.Append(v4);
-                   subbrep_add_planar_face(data->parent, &pcyl, &vert_loop, 
negative);
+                   subbrep_add_planar_face(data->parent, &pcyl, &vert_loop, 
data->negative_shape);
                }
            }
 
@@ -833,23 +795,9 @@
                    // cylinder surface.  Whether the comb is actually 
subtracted from the
                    // global object or unioned into a comb lower down the tree 
(or vice versa)
                    // is determined later.
-                   int negative = negative_cylinder(data, 
*cylindrical_surfaces.begin(), cyl_tol);
+                   data->negative_shape = negative_cylinder(data, 
*cylindrical_surfaces.begin(), cyl_tol);
+                   data->params->bool_op = (data->negative_shape == -1) ? '-' 
: 'u';
 
-                   if (data->parent->params->bool_op == '-') negative = -1 * 
negative;
-
-                   switch (negative) {
-                       case -1:
-                           data->params->bool_op = '-';
-                           break;
-                       case 1:
-                           data->params->bool_op = 'u';
-                           break;
-                       default:
-                           std::cout << "Could not determine cylinder 
status???????\n";
-                           data->params->bool_op = 'u';
-                           break;
-                   }
-
                    // cylinder - positive object in this sub-comb
                    cyl_obj->params->bool_op = 'u';
                    VMOVE(cyl_obj->params->origin, ip1);
@@ -1082,7 +1030,7 @@
                                vert_loop.Append(v2);
                                vert_loop.Append(v3);
                                vert_loop.Append(v4);
-                               subbrep_add_planar_face(data->parent, &pcyl, 
&vert_loop, negative);
+                               subbrep_add_planar_face(data->parent, &pcyl, 
&vert_loop, data->negative_shape);
                            }
                        }
 

Modified: brlcad/trunk/src/libbrep/shape_recognition_sphere.cpp
===================================================================
--- brlcad/trunk/src/libbrep/shape_recognition_sphere.cpp       2015-03-12 
01:50:28 UTC (rev 64374)
+++ brlcad/trunk/src/libbrep/shape_recognition_sphere.cpp       2015-03-12 
15:23:00 UTC (rev 64375)
@@ -219,23 +219,9 @@
        // sphere surface.  Whether the comb is actually subtracted from the
        // global object or unioned into a comb lower down the tree (or vice 
versa)
        // is determined later.
-       int negative = negative_sphere(data, *spherical_surfaces.begin(), 
sph_tol);
+       data->negative_shape = negative_sphere(data, 
*spherical_surfaces.begin(), sph_tol);
+       data->params->bool_op = (data->negative_shape == -1) ? '-' : 'u';
 
-       if (data->parent->params->bool_op == '-') negative = -1 * negative;
-
-       switch (negative) {
-           case -1:
-               data->params->bool_op = '-';
-               break;
-           case 1:
-               data->params->bool_op = 'u';
-               break;
-           default:
-               std::cout << "Could not determine sphere status???????\n";
-               data->params->bool_op = 'u';
-               break;
-       }
-
        // Add the sphere - unioned top level for this sub-comb
        sph_obj->params->bool_op = 'u';
        sph_obj->params->origin[0] = sph.Center().x;
@@ -252,7 +238,7 @@
            if (!data->parent->planar_obj) {
                subbrep_planar_init(data);
            }
-           subbrep_add_planar_face(data->parent, &back_plane, &sph_verts, 
negative);
+           subbrep_add_planar_face(data->parent, &back_plane, &sph_verts, 
data->negative_shape);
        }
 
        // The planes each define an arb8 (4 all together) that carve the

Modified: brlcad/trunk/src/libbrep/shape_recognition_util.cpp
===================================================================
--- brlcad/trunk/src/libbrep/shape_recognition_util.cpp 2015-03-12 01:50:28 UTC 
(rev 64374)
+++ brlcad/trunk/src/libbrep/shape_recognition_util.cpp 2015-03-12 15:23:00 UTC 
(rev 64375)
@@ -223,6 +223,7 @@
     obj->local_brep = NULL;
     obj->type = BREP;
     obj->is_island = 0;
+    obj->negative_shape = 0;
 }
 
 void
@@ -462,9 +463,10 @@
    // Determine what we have.  If we have both pos and neg counts > 0,
    // the proposed brep needs to be broken down further.  all pos
    // counts is a union, all neg counts is a subtraction
-   if (pos_cnt && neg_cnt) return 0;
+   if (pos_cnt && neg_cnt) return -2;
    if (pos_cnt) return 1;
    if (neg_cnt) return -1;
+   if (!pos_cnt && !neg_cnt) return 2;
 }
 
 /* Find corners that can be used to construct a planar face

Modified: brlcad/trunk/src/librt/test_shape_recognition.cpp
===================================================================
--- brlcad/trunk/src/librt/test_shape_recognition.cpp   2015-03-12 01:50:28 UTC 
(rev 64374)
+++ brlcad/trunk/src/librt/test_shape_recognition.cpp   2015-03-12 15:23:00 UTC 
(rev 64375)
@@ -366,6 +366,7 @@
            subbrep_obj_name(data, &brep_name);
            mk_brep(wdbp, bu_vls_addr(&brep_name), data->local_brep);
            // TODO - almost certainly need to do more work to get correct 
booleans
+           //std::cout << bu_vls_addr(&brep_name) << ": " << 
data->params->bool_op << "\n";
            if (pcomb) (void)mk_addmember(bu_vls_addr(&brep_name), &(pcomb->l), 
NULL, db_str2op(&(data->params->bool_op)));
            bu_vls_free(&brep_name);
        } else {
@@ -392,6 +393,7 @@
            mk_lcomb(wdbp, bu_vls_addr(&comb_name), &wcomb, 0, NULL, NULL, 
NULL, 0);
 
            // TODO - almost certainly need to do more work to get correct 
booleans
+           //std::cout << bu_vls_addr(&comb_name) << ": " << 
data->params->bool_op << "\n";
            if (pcomb) (void)mk_addmember(bu_vls_addr(&comb_name), &(pcomb->l), 
NULL, db_str2op(&(data->params->bool_op)));
 
            bu_vls_free(&member_name);
@@ -453,6 +455,7 @@
     BU_LIST_INIT(&pcomb.l);
 
     struct bu_ptbl *subbreps = find_subbreps(brep);
+    struct bu_ptbl *subbreps_tree = find_top_level_hierarchy(subbreps);
     for (unsigned int i = 0; i < BU_PTBL_LEN(subbreps); i++){
        struct subbrep_object_data *obj = (struct subbrep_object_data 
*)BU_PTBL_GET(subbreps, i);
        //print_subbrep_object(obj, "");
@@ -461,12 +464,11 @@
        //BU_PUT(obj, struct subbrep_object_data);
     }
 
-    struct bu_ptbl *subbreps_tree = find_top_level_hierarchy(subbreps);
     for (unsigned int i = 0; i < BU_PTBL_LEN(subbreps_tree); i++){
        struct subbrep_object_data *obj = (struct subbrep_object_data 
*)BU_PTBL_GET(subbreps_tree, i);
-       std::cout << "Key: " << bu_vls_addr(obj->key) << "\n";
        struct bu_vls obj_name = BU_VLS_INIT_ZERO;
        subbrep_obj_name(obj, &obj_name);
+       //std::cout << bu_vls_addr(&obj_name) << ": " << obj->params->bool_op 
<< "\n";
        (void)mk_addmember(bu_vls_addr(&obj_name), &(pcomb.l), NULL, 
db_str2op(&(obj->params->bool_op)));
     }
 

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to