Revision: 64354
          http://sourceforge.net/p/brlcad/code/64354
Author:   starseeker
Date:     2015-03-10 00:39:56 +0000 (Tue, 10 Mar 2015)
Log Message:
-----------
Try using a slight tweak of the cylinder arb logic for cones.  If this works, 
probably need to refactor arb object creation into its own function.

Modified Paths:
--------------
    brlcad/trunk/src/libbrep/shape_recognition_cone.cpp

Modified: brlcad/trunk/src/libbrep/shape_recognition_cone.cpp
===================================================================
--- brlcad/trunk/src/libbrep/shape_recognition_cone.cpp 2015-03-09 21:29:01 UTC 
(rev 64353)
+++ brlcad/trunk/src/libbrep/shape_recognition_cone.cpp 2015-03-10 00:39:56 UTC 
(rev 64354)
@@ -303,9 +303,9 @@
        ON_3dVector hvect = set2_c.Center() - set1_c.Center();
 
        int *corner_verts_array = NULL;
-       ON_Plane pcyl;
+       ON_Plane pcone;
        std::set<int> corner_verts; /* verts with one nonlinear edge */
-       int corner_verts_cnt = subbrep_find_corners(data, &corner_verts_array, 
&pcyl);
+       int corner_verts_cnt = subbrep_find_corners(data, &corner_verts_array, 
&pcone);
 
        if (corner_verts_cnt == -1) return 0;
        if (corner_verts_cnt > 0) {
@@ -389,7 +389,187 @@
 
            bu_ptbl_ins(data->children, (long *)cone_obj);
 
+            // arb8 - subtracted from the previous cone in this sub-comb
 
+            //                                       8
+            //                                    *  |   *
+            //                                 *     |       *
+            //                             4         |           7
+            //                             |    *    |        *  |
+            //                             |         *     *     |
+            //                             |         |  3        |
+            //                             |         |  |        |
+            //                             |         |  |        |
+            //                             |         5  |        |
+            //                             |       *    |*       |
+            //                             |   *        |    *   |
+            //                             1            |        6
+            //                                 *        |     *
+            //                                      *   |  *
+            //                                          2
+            //
+
+            struct subbrep_object_data *arb_obj;
+            BU_GET(arb_obj, struct subbrep_object_data);
+            subbrep_object_init(arb_obj, data->brep);
+            bu_vls_sprintf(arb_obj->key, "%s_arb8", key.c_str());
+            arb_obj->type = ARB8;
+
+
+            // First, find the two points closest to the set1_c and set2_c 
planes
+            ON_SimpleArray<const ON_BrepVertex *> bottom_pnts(2);
+            ON_SimpleArray<const ON_BrepVertex *> top_pnts(2);
+            ON_Plane b_plane = set1_c.Plane();
+            ON_Plane t_plane = set2_c.Plane();
+            if (subbrep_top_bottom_pnts(data, &corner_verts, &t_plane, 
&b_plane, &top_pnts, &bottom_pnts)) {
+                std::cout << "Point top/bottom sorting failed\n";
+                return 0;
+            }
+
+            // Second, select a point from an arc edge not on the subtraction
+            // plane, construct a vector from the circle center to that point,
+            // and determine if the pcone plane direction is already in the 
opposite
+            // direction or needs to be reversed.
+            const ON_BrepEdge *edge = &(data->brep->m_E[*arc_set_1.begin()]);
+            ON_Arc arc;
+            ON_Curve *ecv = edge->EdgeCurveOf()->Duplicate();
+            (void)ecv->IsArc(NULL, &arc, cone_tol);
+            delete ecv;
+            ON_3dPoint center = set1_c.Center();
+            ON_3dPoint midpt = arc.MidPoint();
+
+            ON_3dVector invec = center - midpt;
+            double dotp = ON_DotProduct(invec, pcone.Normal());
+            if (dotp < 0) {
+                pcone.Flip();
+            }
+
+            // Third, construct the axis vector and determine the arb
+            // order of the bottom and top points
+            ON_3dVector cone_axis = set2_c.Center() - set1_c.Center();
+
+            ON_3dVector vv1 = bottom_pnts[0]->Point() - 
bottom_pnts[1]->Point();
+            ON_3dVector v1x = ON_CrossProduct(vv1, cone_axis);
+
+            double flag1 = ON_DotProduct(v1x, pcone.Normal());
+
+            ON_3dVector w1 = top_pnts[0]->Point() - top_pnts[1]->Point();
+            ON_3dVector w1x = ON_CrossProduct(w1, cone_axis);
+
+            double flag3 = ON_DotProduct(w1x, pcone.Normal());
+
+            const ON_BrepVertex *v1, *v2, *v3, *v4;
+            if (flag1 < 0) {
+                v1 = bottom_pnts[1];
+                v2 = bottom_pnts[0];
+                vv1 = -vv1;
+            } else {
+                v1 = bottom_pnts[0];
+                v2 = bottom_pnts[1];
+            }
+            if (flag3 < 0) {
+                v3 = top_pnts[0];
+                v4 = top_pnts[1];
+            } else {
+                v3 = top_pnts[1];
+                v4 = top_pnts[0];
+            }
+#if 0
+            std::cout << "v1 (" << pout(v1->Point()) << ")\n";
+            std::cout << "v2 (" << pout(v2->Point()) << ")\n";
+            std::cout << "v3 (" << pout(v3->Point()) << ")\n";
+            std::cout << "v4 (" << pout(v4->Point()) << ")\n";
+#endif
+
+            // Before we manipulate the points for arb construction,
+            // see if we need to use them to define a new face.
+            if (!data->is_island) {
+                // The coneinder shape is a partial coneinder, and it is not
+                // topologically isolated, so we need to make a new face
+                // in the parent to replace this one.
+                if (data->parent) {
+                    // First, see if a local planar brep object has been 
generated for
+                    // this shape.  Such a brep is not generated up front, 
because
+                    // there is no way to be sure a planar parent is needed 
until
+                    // we hit a case like this - for example, a brep 
consisting of
+                    // stacked coneinders of different diameters will have 
multiple
+                    // planar surfaces, but can be completely described 
without use
+                    // of planar volumes in the final CSG expression.  If 
another
+                    // shape has already triggered the generation we don't 
want to
+                    // do it again,  but the first shape to make the need 
clear has
+                    // to trigger the build.
+                    if (!data->parent->planar_obj) {
+                        subbrep_planar_init(data);
+                    }
+                    // Now, add the new face
+                    ON_SimpleArray<const ON_BrepVertex *> vert_loop(4);
+                    vert_loop.Append(v1);
+                    vert_loop.Append(v2);
+                    vert_loop.Append(v3);
+                    vert_loop.Append(v4);
+                    subbrep_add_planar_face(data->parent, &pcone, &vert_loop, 
negative);
+                }
+            }
+
+
+
+            // Once the 1,2,3,4 points are determined, scale them out
+            // along their respective line segment axis to make sure
+            // the resulting arb is large enough to subtract the full
+            // radius of the coneinder.
+            //
+            // TODO - Only need to do this if the
+            // center point of the coneinder is inside the subtracting arb -
+            // should be able to test that with the circle center point
+            // a distance to pcone plane calculation for the second point,
+            // then subtract the center from the point on the plane and do
+            // a dot product test with pcone's normal.
+            //
+            // TODO - Can optimize this - can make a narrower arb using
+            // the knowledge of the distance between p1/p2.  We only need
+            // to add enough extra length to clear the coneinder, which
+           // means the full radius length is almost always overkill.
+           double max_radius = set1_c.Radius();
+           if (set2_c.Radius() > max_radius) max_radius = set2_c.Radius();
+           ON_SimpleArray<ON_3dPoint> arb_points(8);
+           arb_points[0] = v1->Point();
+            arb_points[1] = v2->Point();
+            arb_points[2] = v3->Point();
+            arb_points[3] = v4->Point();
+            vv1.Unitize();
+            vv1 = vv1 * max_radius;
+            arb_points[0] = arb_points[0] + vv1;
+            arb_points[1] = arb_points[1] - vv1;
+            arb_points[2] = arb_points[2] - vv1;
+            arb_points[3] = arb_points[3] + vv1;
+            ON_3dVector hpad = arb_points[2] - arb_points[1];
+            hpad.Unitize();
+            hpad = hpad * (cone_axis.Length() * 0.01);
+            arb_points[0] = arb_points[0] - hpad;
+            arb_points[1] = arb_points[1] - hpad;
+            arb_points[2] = arb_points[2] + hpad;
+            arb_points[3] = arb_points[3] + hpad;
+
+            // Once the final 1,2,3,4 points have been determined, use
+            // the pcone normal direction and the coneinder radius to
+            // construct the remaining arb points.
+            ON_3dPoint p5, p6, p7, p8;
+            ON_3dVector arb_side = pcone.Normal() * 2*max_radius;
+            arb_points[4] = arb_points[0] + arb_side;
+            arb_points[5] = arb_points[1] + arb_side;
+            arb_points[6] = arb_points[2] + arb_side;
+            arb_points[7] = arb_points[3] + arb_side;
+
+            arb_obj->params->bool_op = '-';
+            arb_obj->params->arb_type = 8;
+            for (int j = 0; j < 8; j++) {
+                VMOVE(arb_obj->params->p[j], arb_points[j]);
+            }
+
+            bu_ptbl_ins(data->children, (long *)arb_obj);
+
+            return 1;
+
        }
     }
     return 0;

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