Revision: 65233
          http://sourceforge.net/p/brlcad/code/65233
Author:   ejno
Date:     2015-06-09 20:57:42 +0000 (Tue, 09 Jun 2015)
Log Message:
-----------
recognize COMPSPLT objects (in progress)

Modified Paths:
--------------
    brlcad/trunk/src/libgcv/conv/fastgen4/fastgen4_write.cpp

Modified: brlcad/trunk/src/libgcv/conv/fastgen4/fastgen4_write.cpp
===================================================================
--- brlcad/trunk/src/libgcv/conv/fastgen4/fastgen4_write.cpp    2015-06-09 
19:51:23 UTC (rev 65232)
+++ brlcad/trunk/src/libgcv/conv/fastgen4/fastgen4_write.cpp    2015-06-09 
20:57:42 UTC (rev 65233)
@@ -123,6 +123,91 @@
 }
 
 
+class DBInternal
+{
+public:
+    static const directory &lookup(const db_i &db, const std::string &name);
+
+    DBInternal();
+    DBInternal(const db_i &db, const directory &dir);
+    ~DBInternal();
+
+    void load(const db_i &db, const directory &dir);
+    const rt_db_internal &get() const;
+
+
+private:
+    DBInternal(const DBInternal &source);
+    DBInternal &operator=(const DBInternal &source);
+
+    bool m_valid;
+    rt_db_internal m_internal;
+};
+
+
+const directory &
+DBInternal::lookup(const db_i &db, const std::string &name)
+{
+    const directory *dir = db_lookup(&db, name.c_str(), LOOKUP_QUIET);
+
+    if (!dir)
+       throw std::invalid_argument("db_lookup() failed");
+
+    return *dir;
+}
+
+
+DBInternal::DBInternal() :
+    m_valid(false),
+    m_internal()
+{}
+
+
+DBInternal::DBInternal(const db_i &db, const directory &dir) :
+    m_valid(false),
+    m_internal()
+{
+    load(db, dir);
+}
+
+
+inline
+DBInternal::~DBInternal()
+{
+    if (m_valid)
+       rt_db_free_internal(&m_internal);
+}
+
+
+void
+DBInternal::load(const db_i &db, const directory &dir)
+{
+    RT_CK_DBI(&db);
+    RT_CK_DIR(&dir);
+
+    if (m_valid) {
+       rt_db_free_internal(&m_internal);
+       m_valid = false;
+    }
+
+    if (rt_db_get_internal(&m_internal, &dir, &db, NULL, &rt_uniresource) < 0)
+       throw std::runtime_error("rt_db_get_internal() failed");
+
+    RT_CK_DB_INTERNAL(&m_internal);
+    m_valid = true;
+}
+
+
+inline const rt_db_internal &
+DBInternal::get() const
+{
+    if (!m_valid)
+       throw std::logic_error("invalid");
+
+    return m_internal;
+}
+
+
 class RecordWriter
 {
 public:
@@ -305,6 +390,7 @@
     ~FastgenWriter();
 
     void write_section_color(const SectionID &section_id, const Color &color);
+    SectionID write_compsplt(const SectionID &id, fastf_t z_coordinate);
 
     enum BooleanType { HOLE, WALL };
     void write_boolean(BooleanType type, const SectionID &section_a,
@@ -378,6 +464,20 @@
 }
 
 
+FastgenWriter::SectionID
+FastgenWriter::write_compsplt(const SectionID &id, fastf_t z_coordinate)
+{
+    SectionID result = take_next_section_id();
+
+    Record record(*this);
+    record << "COMPSPLT" << id.first << id.second;
+    record << result.first << result.second;
+    record << z_coordinate;
+
+    return result;
+}
+
+
 void
 FastgenWriter::write_boolean(BooleanType type, const SectionID &section_a,
                             const SectionID &section_b, const SectionID 
*section_c,
@@ -958,91 +1058,31 @@
 }
 
 
-class DBInternal
+const directory *
+get_region_dir(const db_i &db, const db_full_path &path)
 {
-public:
-    static const directory &lookup(const db_i &db, const std::string &name);
+    RT_CK_DBI(&db);
+    RT_CK_FULL_PATH(&path);
 
-    DBInternal();
-    DBInternal(const db_i &db, const directory &dir);
-    ~DBInternal();
+    for (std::size_t i = 0; i < path.fp_len; ++i) {
+       DBInternal comb_db_internal(db, *DB_FULL_PATH_GET(&path, i));
 
-    void load(const db_i &db, const directory &dir);
-    const rt_db_internal &get() const;
+       if ((i == path.fp_len - 1)
+           && comb_db_internal.get().idb_minor_type != ID_COMBINATION)
+           continue;
 
+       const rt_comb_internal &comb_internal = *static_cast<rt_comb_internal *>
+                                               
(comb_db_internal.get().idb_ptr);
+       RT_CK_COMB(&comb_internal);
 
-private:
-    DBInternal(const DBInternal &source);
-    DBInternal &operator=(const DBInternal &source);
-
-    bool m_valid;
-    rt_db_internal m_internal;
-};
-
-
-const directory &
-DBInternal::lookup(const db_i &db, const std::string &name)
-{
-    const directory *dir = db_lookup(&db, name.c_str(), LOOKUP_QUIET);
-
-    if (!dir)
-       throw std::invalid_argument("db_lookup() failed");
-
-    return *dir;
-}
-
-
-DBInternal::DBInternal() :
-    m_valid(false),
-    m_internal()
-{}
-
-
-DBInternal::DBInternal(const db_i &db, const directory &dir) :
-    m_valid(false),
-    m_internal()
-{
-    load(db, dir);
-}
-
-
-inline
-DBInternal::~DBInternal()
-{
-    if (m_valid)
-       rt_db_free_internal(&m_internal);
-}
-
-
-void
-DBInternal::load(const db_i &db, const directory &dir)
-{
-    RT_CK_DBI(&db);
-    RT_CK_DIR(&dir);
-
-    if (m_valid) {
-       rt_db_free_internal(&m_internal);
-       m_valid = false;
+       if (comb_internal.region_flag)
+           return DB_FULL_PATH_GET(&path, i);
     }
 
-    if (rt_db_get_internal(&m_internal, &dir, &db, NULL, &rt_uniresource) < 0)
-       throw std::runtime_error("rt_db_get_internal() failed");
-
-    RT_CK_DB_INTERNAL(&m_internal);
-    m_valid = true;
+    return NULL; // no parent region
 }
 
 
-inline const rt_db_internal &
-DBInternal::get() const
-{
-    if (!m_valid)
-       throw std::logic_error("invalid");
-
-    return m_internal;
-}
-
-
 HIDDEN bool
 get_cutout(const db_i &db, const db_full_path &path, DBInternal &outer,
           DBInternal &inner)
@@ -1253,6 +1293,142 @@
 }
 
 
+HIDDEN void
+get_unioned(const db_i &db, const tree *tree,
+           std::set<const directory *> &results)
+{
+    RT_CK_DBI(&db);
+
+    if (!tree)
+       return;
+
+    RT_CK_TREE(tree);
+
+    switch (tree->tr_op) {
+       case OP_NOP:
+           break;
+
+       case OP_DB_LEAF:
+           results.insert(&DBInternal::lookup(db, tree->tr_l.tl_name));
+           break;
+
+       case OP_UNION:
+           get_unioned(db, tree->tr_b.tb_left, results);
+           get_unioned(db, tree->tr_b.tb_right, results);
+           break;
+
+       case OP_SUBTRACT:
+           get_unioned(db, tree->tr_b.tb_left, results);
+           break;
+    }
+}
+
+
+HIDDEN void
+get_intersected(const db_i &db, const tree *tree,
+               std::set<const directory *> &results)
+{
+    RT_CK_DBI(&db);
+
+    if (!tree)
+       return;
+
+    RT_CK_TREE(tree);
+
+    switch (tree->tr_op) {
+       case OP_NOP:
+           break;
+
+       case OP_INTERSECT:
+           get_unioned(db, tree->tr_b.tb_left, results);
+           get_unioned(db, tree->tr_b.tb_right, results);
+           break;
+
+       case OP_UNION:
+           get_intersected(db, tree->tr_b.tb_left, results);
+           get_intersected(db, tree->tr_b.tb_right, results);
+           break;
+
+       case OP_SUBTRACT:
+           get_intersected(db, tree->tr_b.tb_left, results);
+           break;
+    }
+}
+
+
+HIDDEN void
+get_subtracted(const db_i &db, const tree *tree,
+              std::set<const directory *> &results)
+{
+    RT_CK_DBI(&db);
+
+    if (!tree)
+       return;
+
+    RT_CK_TREE(tree);
+
+    switch (tree->tr_op) {
+       case OP_NOP:
+           break;
+
+       case OP_UNION:
+       case OP_INTERSECT:
+           get_subtracted(db, tree->tr_b.tb_left, results);
+           get_subtracted(db, tree->tr_b.tb_right, results);
+           break;
+
+       case OP_SUBTRACT:
+           get_subtracted(db, tree->tr_b.tb_left, results);
+           get_unioned(db, tree->tr_b.tb_right, results);
+           break;
+    }
+}
+
+
+HIDDEN bool
+find_compsplt(Section &section, const db_i &db, const db_full_path &path,
+             const rt_half_internal &half)
+{
+    RT_CK_DBI(&db);
+    RT_CK_FULL_PATH(&path);
+    RT_HALF_CK_MAGIC(&half);
+
+    const vect_t normal = {0.0, 0.0, 1.0};
+
+    if (!VNEAR_EQUAL(half.eqn, normal, RT_LEN_TOL))
+       return false;
+
+    // ensure that the halfspace is subtracted from the parent region
+    DBInternal parent_region_internal;
+
+    if (const directory *parent_region_dir = get_region_dir(db, path))
+       parent_region_internal.load(db, *parent_region_dir);
+    else
+       return false;
+
+    const rt_comb_internal &parent_region = *static_cast<rt_comb_internal *>
+                                           
(parent_region_internal.get().idb_ptr);
+    RT_CK_COMB(&parent_region);
+
+    std::set<const directory *> leaves;
+    get_intersected(db, parent_region.tree, leaves);
+
+    if (leaves.count(DB_FULL_PATH_CUR_DIR(&path))) {
+       // this is one half of the compsplt
+    } else {
+       leaves.clear();
+       get_subtracted(db, parent_region.tree, leaves);
+
+       if (!leaves.count(DB_FULL_PATH_CUR_DIR(&path)))
+           return false; // not a compsplt
+
+       // here we have the other half
+    }
+
+    return false;
+}
+
+
 struct FastgenConversion {
     FastgenConversion(const std::string &path, const db_i &db, const bn_tol 
&tol);
     ~FastgenConversion();
@@ -1270,8 +1446,6 @@
     FastgenConversion(const FastgenConversion &source);
     FastgenConversion &operator=(const FastgenConversion &source);
 
-    const directory * get_region_dir(const db_full_path &path) const;
-
     std::map<const directory *, Section *> m_sections;
 };
 
@@ -1304,35 +1478,11 @@
 }
 
 
-const directory *
-FastgenConversion::get_region_dir(const db_full_path &path) const
-{
-    RT_CK_FULL_PATH(&path);
-
-    for (std::size_t i = 0; i < path.fp_len; ++i) {
-       DBInternal comb_db_internal(m_db, *DB_FULL_PATH_GET(&path, i));
-
-       if ((i == path.fp_len - 1)
-           && comb_db_internal.get().idb_minor_type != ID_COMBINATION)
-           continue;
-
-       const rt_comb_internal &comb_internal = *static_cast<rt_comb_internal *>
-                                               
(comb_db_internal.get().idb_ptr);
-       RT_CK_COMB(&comb_internal);
-
-       if (comb_internal.region_flag)
-           return DB_FULL_PATH_GET(&path, i);
-    }
-
-    return NULL; // no parent region
-}
-
-
 void
 FastgenConversion::create_section(const db_full_path &path)
 {
     std::pair<std::map<const directory *, Section *>::iterator, bool> found =
-       m_sections.insert(std::make_pair(get_region_dir(path),
+       m_sections.insert(std::make_pair(get_region_dir(m_db, path),
                                         static_cast<Section *>(NULL)));
 
     if (!found.second)
@@ -1348,117 +1498,11 @@
 FastgenConversion::get_section(const db_full_path &path)
 {
     RT_CK_FULL_PATH(&path);
-    return *m_sections.at(get_region_dir(path));
+    return *m_sections.at(get_region_dir(m_db, path));
 }
 
 
 HIDDEN bool
-get_walls_helper_extract_solids(const db_i &db, const tree *tree,
-                               std::set<const directory *> &results)
-{
-    RT_CK_DBI(&db);
-
-    if (!tree || tree->tr_op == OP_NOP) {
-       return true;
-    } else if (tree->tr_op == OP_UNION) {
-       return get_walls_helper_extract_solids(db, tree->tr_b.tb_left, results)
-              && get_walls_helper_extract_solids(db, tree->tr_b.tb_right, 
results);
-    } else if (tree->tr_op == OP_DB_LEAF) {
-       return results.insert(&DBInternal::lookup(db, 
tree->tr_l.tl_name)).second;
-    } else {
-       return false;
-    }
-}
-
-
-HIDDEN std::vector<const directory *>
-get_walls_helper_find_regions(const db_i &db,
-                             std::set<const directory *> &subtracted)
-{
-    RT_CK_DBI(&db);
-
-    std::vector<const directory *> results;
-
-    directory **regions;
-    std::size_t num_regions = db_ls(&db, DB_LS_REGION, NULL, &regions);
-    AutoFreePtr<directory *> autofree_regions(regions);
-
-    for (std::size_t i = 0; i < num_regions; ++i) {
-       DBInternal region_db_internal(db, *regions[i]);
-       const rt_comb_internal &region_internal = *static_cast<rt_comb_internal 
*>
-               (region_db_internal.get().idb_ptr);
-       RT_CK_COMB(&region_internal);
-       std::set<const directory *> unioned;
-       get_walls_helper_extract_solids(db, region_internal.tree, unioned);
-
-       // FIXME check transforms
-
-       bool success = false;
-
-       for (std::set<const directory *>::const_iterator it = unioned.begin();
-            it != unioned.end(); ++it) {
-           if (subtracted.erase(*it))
-               success = true;
-       }
-
-       if (success)
-           results.push_back(regions[i]);
-    }
-
-    return results;
-}
-
-
-HIDDEN void
-get_walls(const FastgenConversion &data, const db_full_path &path)
-{
-    RT_CK_FULL_PATH(&path);
-
-    std::set<const directory *> subtracted;
-    {
-       DBInternal self_internal(data.m_db, *DB_FULL_PATH_CUR_DIR(&path));
-
-       if (self_internal.get().idb_minor_type != ID_COMBINATION)
-           return;
-
-       const rt_comb_internal &comb = *static_cast<rt_comb_internal *>
-                                      (self_internal.get().idb_ptr);
-       RT_CK_COMB(&comb);
-
-       // check that structure is similar to an imported WALL
-       // TODO: other compatible possibilities
-       if (comb.tree->tr_op != OP_SUBTRACT)
-           return;
-
-       const tree::tree_node &b = comb.tree->tr_b;
-
-       if (!b.tb_left || !b.tb_right || b.tb_left->tr_op != OP_DB_LEAF
-           || (b.tb_right->tr_op != OP_DB_LEAF && b.tb_right->tr_op != 
OP_UNION))
-           return;
-
-       if (b.tb_right->tr_op == OP_DB_LEAF) {
-           subtracted.insert(&DBInternal::lookup(data.m_db, 
b.tb_right->tr_l.tl_name));
-       } else if (b.tb_right->tr_op == OP_UNION) {
-           if (!get_walls_helper_extract_solids(data.m_db, b.tb_right, 
subtracted))
-               return;
-       } else {
-           return;
-       }
-    }
-
-    std::vector<const directory *> subtracted_regions =
-       get_walls_helper_find_regions(data.m_db, subtracted);
-
-    if (!subtracted.empty())
-       return; // holes?
-
-    for (std::vector<const directory *>::const_iterator it =
-            subtracted_regions.begin(); it != subtracted_regions.end(); ++it)
-       bu_log("DEBUG: %s\n", (*it)->d_namep);
-}
-
-
-HIDDEN bool
 convert_primitive(FastgenConversion &data, const db_full_path &path,
                  const rt_db_internal &internal)
 {
@@ -1536,6 +1580,17 @@
            break;
        }
 
+       case ID_HALF: {
+           const rt_half_internal &half = *static_cast<rt_half_internal *>
+                                          (internal.idb_ptr);
+           RT_HALF_CK_MAGIC(&half);
+
+           if (!find_compsplt(section, data.m_db, path, half))
+               return false;
+           else
+               break;
+       }
+
        default:
            return false;
     }
@@ -1638,7 +1693,6 @@
     FastgenConversion &data = *static_cast<FastgenConversion *>(client_data);
     Section &section = data.get_section(*path);
     section.set_color(color_from_floats(tree_state->ts_mater.ma_color));
-    get_walls(data, *path);
 
     if (current_tree->tr_op != OP_NOP) {
        gcv_region_end_data gcv_data = {write_nmg_region, &data};

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


------------------------------------------------------------------------------
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to