Revision: 65188
http://sourceforge.net/p/brlcad/code/65188
Author: ejno
Date: 2015-06-04 21:07:30 +0000 (Thu, 04 Jun 2015)
Log Message:
-----------
write regions to fg4 sections in the region-end function; enable export of
primitives
Modified Paths:
--------------
brlcad/trunk/src/libgcv/conv/fastgen4/NOTES
brlcad/trunk/src/libgcv/conv/fastgen4/fastgen4_write.cpp
Modified: brlcad/trunk/src/libgcv/conv/fastgen4/NOTES
===================================================================
--- brlcad/trunk/src/libgcv/conv/fastgen4/NOTES 2015-06-04 20:28:10 UTC (rev
65187)
+++ brlcad/trunk/src/libgcv/conv/fastgen4/NOTES 2015-06-04 21:07:30 UTC (rev
65188)
@@ -1,3 +1,6 @@
+primitives
+ - CQUAD elements
+
Boolean operations:
- Unions on primitives may be representable using the WALL record.
- If an fg4 primitive has a facetized object subtracted from it, the
facetized object will currently not be output (tree appears empty).
Modified: brlcad/trunk/src/libgcv/conv/fastgen4/fastgen4_write.cpp
===================================================================
--- brlcad/trunk/src/libgcv/conv/fastgen4/fastgen4_write.cpp 2015-06-04
20:28:10 UTC (rev 65187)
+++ brlcad/trunk/src/libgcv/conv/fastgen4/fastgen4_write.cpp 2015-06-04
21:07:30 UTC (rev 65188)
@@ -205,8 +205,7 @@
class StringBuffer : public RecordWriter
{
public:
- StringBuffer(RecordWriter &writer);
- virtual ~StringBuffer();
+ void write(RecordWriter &writer) const;
protected:
@@ -214,22 +213,14 @@
private:
- RecordWriter &m_writer;
std::ostringstream m_ostringstream;
};
-inline
-StringBuffer::StringBuffer(RecordWriter &writer) :
- m_writer(writer),
- m_ostringstream()
-{}
-
-
-inline
-StringBuffer::~StringBuffer()
+inline void
+StringBuffer::write(RecordWriter &writer) const
{
- RecordWriter::Record record(m_writer);
+ RecordWriter::Record record(writer);
record.text(m_ostringstream.str());
}
@@ -253,11 +244,12 @@
void write_comment(const std::string &value);
void write_section_color(const SectionID §ion_id,
const unsigned char *color);
- void write_hole(const SectionID &surrounding_id,
- const std::vector<SectionID> &subtracted_ids);
- void write_wall(const SectionID &surrounding_id,
- const std::vector<SectionID> &subtracted_ids);
+ enum BooleanType { HOLE, WALL };
+ void write_boolean(BooleanType type, const SectionID §ion_a,
+ const SectionID §ion_b, const SectionID *section_c =
NULL,
+ const SectionID *section_d = NULL);
+
SectionID take_next_section_id();
@@ -333,36 +325,21 @@
void
-FastgenWriter::write_hole(const SectionID &surrounding_id,
- const std::vector<SectionID> &subtracted_ids)
+FastgenWriter::write_boolean(BooleanType type, const SectionID §ion_a,
+ const SectionID §ion_b, const SectionID
*section_c,
+ const SectionID *section_d)
{
- if (subtracted_ids.empty() || subtracted_ids.size() > 3)
- throw std::invalid_argument("invalid number of IDs");
-
Record record(*this);
- record << "HOLE";
- record << surrounding_id.first << surrounding_id.second;
+ record << (type == HOLE ? "HOLE" : "WALL");
+ record << section_a.first << section_a.second;
- for (std::vector<SectionID>::const_iterator it = subtracted_ids.begin();
- it != subtracted_ids.end(); ++it)
- record << it->first << it->second;
-}
+ record << section_b.first << section_b.second;
+ if (section_c)
+ record << section_c->first << section_c->second;
-void
-FastgenWriter::write_wall(const SectionID &surrounding_id,
- const std::vector<SectionID> &subtracted_ids)
-{
- if (subtracted_ids.empty() || subtracted_ids.size() > 3)
- throw std::invalid_argument("invalid number of IDs");
-
- Record record(*this);
- record << "WALL";
- record << surrounding_id.first << surrounding_id.second;
-
- for (std::vector<SectionID>::const_iterator it = subtracted_ids.begin();
- it != subtracted_ids.end(); ++it)
- record << it->first << it->second;
+ if (section_d)
+ record << section_d->first << section_c->second;
}
@@ -401,14 +378,15 @@
class GridManager
{
public:
- GridManager(RecordWriter &writer);
- ~GridManager();
+ GridManager();
// return a vector of grid IDs corresponding to the given points,
// with no duplicate indices in the returned vector.
std::vector<std::size_t> get_unique_grids(const std::vector<Point>
&points);
+ void write(RecordWriter &writer) const;
+
private:
struct PointComparator {
bool operator()(const Point &lhs, const Point &rhs) const;
@@ -416,7 +394,6 @@
static const std::size_t MAX_GRID_POINTS = 50000;
- RecordWriter &m_writer;
std::size_t m_next_grid_id;
std::map<Point, std::vector<std::size_t>, PointComparator> m_grids;
};
@@ -436,28 +413,12 @@
}
inline
-GridManager::GridManager(RecordWriter &writer) :
- m_writer(writer),
+GridManager::GridManager() :
m_next_grid_id(1),
m_grids()
{}
-GridManager::~GridManager()
-{
- for (std::map<Point, std::vector<std::size_t>,
PointComparator>::const_iterator
- it = m_grids.begin(); it != m_grids.end(); ++it)
- for (std::vector<std::size_t>::const_iterator id_it =
it->second.begin();
- id_it != it->second.end(); ++id_it) {
- FastgenWriter::Record record(m_writer);
- record << "GRID" << *id_it << "";
- record << it->first[X] * INCHES_PER_MM;
- record << it->first[Y] * INCHES_PER_MM;
- record << it->first[Z] * INCHES_PER_MM;
- }
-}
-
-
std::vector<std::size_t>
GridManager::get_unique_grids(const std::vector<Point> &points)
{
@@ -498,12 +459,30 @@
}
+void
+GridManager::write(RecordWriter &writer) const
+{
+ for (std::map<Point, std::vector<std::size_t>,
PointComparator>::const_iterator
+ it = m_grids.begin(); it != m_grids.end(); ++it)
+ for (std::vector<std::size_t>::const_iterator id_it =
it->second.begin();
+ id_it != it->second.end(); ++id_it) {
+ RecordWriter::Record record(writer);
+ record << "GRID" << *id_it << "";
+ record << it->first[X] * INCHES_PER_MM;
+ record << it->first[Y] * INCHES_PER_MM;
+ record << it->first[Z] * INCHES_PER_MM;
+ }
+}
+
+
class Section
{
public:
- Section(FastgenWriter &writer, const std::string &name, bool volume_mode,
- const unsigned char *color = NULL);
+ Section(bool volume_mode = true);
+ void write(FastgenWriter &writer, std::string name,
+ const unsigned char *color = NULL) const;
+
void write_line(const fastf_t *point_a, const fastf_t *point_b,
fastf_t radius, fastf_t thickness);
@@ -523,51 +502,50 @@
private:
static const std::size_t MAX_NAME_SIZE = 25;
- Section(const Section &source);
- Section &operator=(const Section &source);
-
const bool m_volume_mode;
const std::size_t m_material_id;
- FastgenWriter &m_writer;
+ GridManager m_grids;
StringBuffer m_elements;
- GridManager m_grids;
std::size_t m_next_element_id;
};
-Section::Section(FastgenWriter &writer, const std::string &name,
- bool volume_mode, const unsigned char *color) :
+Section::Section(bool volume_mode) :
m_volume_mode(volume_mode),
m_material_id(1),
- m_writer(writer),
- m_elements(m_writer),
- m_grids(m_writer),
+ m_grids(),
+ m_elements(),
m_next_element_id(1)
+{}
+
+
+void
+Section::write(FastgenWriter &writer, std::string name,
+ const unsigned char *color) const
{
- const FastgenWriter::SectionID id = m_writer.take_next_section_id();
+ const FastgenWriter::SectionID id = writer.take_next_section_id();
{
- std::string record_name;
-
if (name.size() > MAX_NAME_SIZE) {
- m_writer.write_comment(name);
- record_name = "..." + name.substr(name.size() - MAX_NAME_SIZE + 3);
- } else {
- record_name = name;
+ writer.write_comment(name);
+ name = "..." + name.substr(name.size() - MAX_NAME_SIZE + 3);
}
- RecordWriter::Record record(m_writer);
+ RecordWriter::Record record(writer);
record << "$NAME" << id.first << id.second;
record << "" << "" << "" << "";
- record.text(record_name);
+ record.text(name);
}
- RecordWriter::Record(m_writer) << "SECTION" << id.first << id.second <<
- (m_volume_mode ? 2 : 1);
+ RecordWriter::Record(writer) << "SECTION" << id.first << id.second <<
+ (m_volume_mode ? 2 : 1);
if (color)
- m_writer.write_section_color(id, color);
+ writer.write_section_color(id, color);
+
+ m_grids.write(writer);
+ m_elements.write(writer);
}
@@ -838,32 +816,6 @@
}
-HIDDEN bool
-tree_entirely_unions(const tree *tree)
-{
- if (!tree)
- return true;
-
- RT_CK_TREE(tree);
-
- switch (tree->tr_op) {
- case OP_SOLID:
- case OP_REGION:
- case OP_NOP:
- case OP_NMG_TESS:
- case OP_DB_LEAF:
- return true; // leaf
-
- case OP_UNION:
- return tree_entirely_unions(tree->tr_b.tb_left)
- && tree_entirely_unions(tree->tr_b.tb_right);
-
- default:
- return false; // non-union operation
- }
-}
-
-
HIDDEN const directory &
get_parent_dir(const db_full_path &path)
{
@@ -876,46 +828,32 @@
}
-HIDDEN rt_db_internal
-get_parent_comb(const db_i &db, const db_full_path &path)
+HIDDEN const directory &
+get_region_dir(const db_i &db, const db_full_path &path)
{
- RT_CK_DBI(&db);
RT_CK_FULL_PATH(&path);
- rt_db_internal comb_db_internal;
+ if (path.fp_len < 2)
+ throw std::invalid_argument("toplevel");
- if (rt_db_get_internal(&comb_db_internal, &get_parent_dir(path), &db,
- NULL, &rt_uniresource) < 0)
- throw std::runtime_error("rt_db_get_internal() failed");
+ for (std::size_t i = 0; i < path.fp_len - 1; ++i) {
+ rt_db_internal comb_db_internal;
- rt_comb_internal &comb_internal = *static_cast<rt_comb_internal *>
- (comb_db_internal.idb_ptr);
- RT_CK_COMB(&comb_internal);
- return comb_db_internal;
-}
+ if (rt_db_get_internal(&comb_db_internal, path.fp_names[i], &db, NULL,
+ &rt_uniresource) < 0)
+ throw std::runtime_error("rt_db_get_internal() failed");
+ AutoFreePtr<rt_db_internal, rt_db_free_internal> autofree_internal(
+ &comb_db_internal);
+ const rt_comb_internal &comb_internal = *static_cast<rt_comb_internal *>
+ (comb_db_internal.idb_ptr);
+ RT_CK_COMB(&comb_internal);
-// Determines whether the parent comb is simple enough
-// to be represented by fastgen4.
-HIDDEN bool
-comb_representable(const db_i &db, const db_full_path &path)
-{
-#if 0
- RT_CK_DBI(&db);
- RT_CK_FULL_PATH(&path);
+ if (comb_internal.region_flag)
+ return *path.fp_names[i];
+ }
- rt_db_internal comb_db_internal = get_parent_comb(db, path);
- AutoFreePtr<rt_db_internal, rt_db_free_internal> autofree_comb_db_internal(
- &comb_db_internal);
-
- rt_comb_internal &comb_internal = *static_cast<rt_comb_internal *>
- (comb_db_internal.idb_ptr);
- return tree_entirely_unions(comb_internal.tree);
-#else
- (void)db;
- (void)path;
- return true;
-#endif
+ throw std::logic_error("no parent region");
}
@@ -925,11 +863,17 @@
RT_CK_DBI(&db);
RT_CK_FULL_PATH(&path)
- rt_db_internal comb_db_internal = get_parent_comb(db, path);
+ rt_db_internal comb_db_internal;
+
+ if (rt_db_get_internal(&comb_db_internal, &get_parent_dir(path), &db,
+ NULL, &rt_uniresource) < 0)
+ throw std::runtime_error("rt_db_get_internal() failed");
+
AutoFreePtr<rt_db_internal, rt_db_free_internal> autofree_comb_db_internal(
&comb_db_internal);
- rt_comb_internal &comb_internal = *static_cast<rt_comb_internal *>
- (comb_db_internal.idb_ptr);
+ const rt_comb_internal &comb_internal = *static_cast<rt_comb_internal *>
+ (comb_db_internal.idb_ptr);
+ RT_CK_COMB(&comb_internal);
const directory *outer_directory, *inner_directory;
{
@@ -1152,20 +1096,62 @@
struct ConversionData {
+ ConversionData(FastgenWriter &writer, const bn_tol &tol, const db_i &db);
+ ~ConversionData();
+
FastgenWriter &m_writer;
const bn_tol &m_tol;
- const bool m_convert_primitives;
+ Section &get_section(const directory *dir);
+ std::map<const directory *, Section *> m_sections;
+
// for cutout detection
const db_i &m_db;
std::set<std::string> m_recorded_cutouts;
+
+
+private:
+ ConversionData(const ConversionData &source);
+ ConversionData &operator=(const ConversionData &source);
};
+ConversionData::ConversionData(FastgenWriter &writer, const bn_tol &tol,
+ const db_i &db) :
+ m_writer(writer),
+ m_tol(tol),
+ m_sections(),
+ m_db(db),
+ m_recorded_cutouts()
+{}
+
+
+ConversionData::~ConversionData()
+{
+ for (std::map<const directory *, Section *>::iterator it =
m_sections.begin();
+ it != m_sections.end(); ++it)
+ delete it->second;
+}
+
+
+Section &
+ConversionData::get_section(const directory *dir)
+{
+ Section *&result = m_sections[dir];
+
+ if (!result)
+ result = new Section;
+
+ return *result;
+}
+
+
HIDDEN bool
-convert_primitive(ConversionData &data, const std::string &name,
- const db_full_path &path, const rt_db_internal &internal)
+convert_primitive(ConversionData &data, const db_full_path &path,
+ const rt_db_internal &internal)
{
+ Section §ion = data.get_section(&get_region_dir(data.m_db, path));
+
switch (internal.idb_type) {
case ID_CLINE: {
const rt_cline_internal &cline = *static_cast<rt_cline_internal *>
@@ -1174,8 +1160,6 @@
point_t v2;
VADD2(v2, cline.v, cline.h);
-
- Section section(data.m_writer, name, true);
section.write_line(cline.v, v2, cline.radius, cline.thickness);
break;
}
@@ -1188,8 +1172,6 @@
if (internal.idb_type != ID_SPH && !ell_is_sphere(ell))
return false;
- Section section(data.m_writer, name, true);
-
if (!find_csphere_cutout(section, data.m_db, path,
data.m_recorded_cutouts))
section.write_sphere(ell.v, MAGNITUDE(ell.a));
@@ -1204,8 +1186,6 @@
if (internal.idb_type != ID_REC && !tgc_is_ccone(tgc))
return false;
- Section section(data.m_writer, name, true);
-
if (!find_ccone_cutout(section, data.m_db, path,
data.m_recorded_cutouts)) {
point_t v2;
VADD2(v2, tgc.v, tgc.h);
@@ -1219,7 +1199,6 @@
const rt_arb_internal &arb = *static_cast<rt_arb_internal
*>(internal.idb_ptr);
RT_ARB_CK_MAGIC(&arb);
- Section section(data.m_writer, name, true);
section.write_hexahedron(arb.pt);
break;
}
@@ -1228,8 +1207,7 @@
const rt_bot_internal &bot = *static_cast<rt_bot_internal
*>(internal.idb_ptr);
RT_BOT_CK_MAGIC(&bot);
- Section section(data.m_writer, name, bot.mode == RT_BOT_SOLID);
-
+ // FIXME Section section(bot.mode == RT_BOT_SOLID);
if (!get_chex1(section, bot))
write_bot(section, bot);
@@ -1261,7 +1239,7 @@
for (BU_LIST_FOR(vshell, shell, &nmg_region->s_hd)) {
NMG_CK_SHELL(vshell);
- rt_bot_internal *bot = nmg_bot(vshell, &data.m_tol);
+ rt_bot_internal * const bot = nmg_bot(vshell, &data.m_tol);
// fill in an rt_db_internal with our new bot so we can free it
rt_db_internal internal;
@@ -1276,8 +1254,9 @@
char_color[0] = static_cast<unsigned char>(color[0] * 255.0 + 0.5);
char_color[1] = static_cast<unsigned char>(color[1] * 255.0 + 0.5);
char_color[2] = static_cast<unsigned char>(color[2] * 255.0 + 0.5);
- Section section(data.m_writer, name, bot->mode == RT_BOT_SOLID,
char_color);
+ Section section(bot->mode == RT_BOT_SOLID);
write_bot(section, *bot);
+ section.write(data.m_writer, name, char_color);
} catch (const std::runtime_error &e) {
bu_log("FAILURE: write_bot() failed on object '%s': %s\n",
name.c_str(),
e.what());
@@ -1298,12 +1277,13 @@
ConversionData &data = *static_cast<ConversionData *>(client_data);
const std::string name = AutoFreePtr<char>(db_path_to_string(path)).ptr;
+
bool converted = false;
+ Section section;
- if (internal->idb_major_type == DB5_MAJORTYPE_BRLCAD
- && data.m_convert_primitives && comb_representable(data.m_db, *path))
+ if (internal->idb_major_type == DB5_MAJORTYPE_BRLCAD)
try {
- converted = convert_primitive(data, name, *path, *internal);
+ converted = convert_primitive(data, *path, *internal);
} catch (const std::runtime_error &e) {
bu_log("FAILURE: convert_primitive() failed on object '%s': %s\n",
name.c_str(),
e.what());
@@ -1329,9 +1309,16 @@
ConversionData &data = *static_cast<ConversionData *>(client_data);
const std::string name = AutoFreePtr<char>(db_path_to_string(path)).ptr;
+ const Section §ion = *data.m_sections.at(path->fp_names[path->fp_len -
1]);
- gcv_region_end_data gcv_data = {write_nmg_region, &data};
- return gcv_region_end(tree_state, path, current_tree, &gcv_data);
+ section.write(data.m_writer, name); // TODO
+
+ if (current_tree->tr_op != OP_NOP) {
+ gcv_region_end_data gcv_data = {write_nmg_region, &data};
+ return gcv_region_end(tree_state, path, current_tree, &gcv_data);
+ }
+
+ return current_tree;
}
@@ -1341,17 +1328,13 @@
{
RT_CK_DBI(dbip);
- // Set to true to directly translate any primitives that can be
represented by fg4.
- // Due to limitations in the fg4 format, boolean operations can not be
represented.
- const bool convert_primitives = false;
-
FastgenWriter writer(path);
writer.write_comment(dbip->dbi_title);
writer.write_comment("g -> fastgen4 conversion");
const rt_tess_tol ttol = {RT_TESS_TOL_MAGIC, 0.0, 0.01, 0.0};
const bn_tol tol = {BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST * BN_TOL_DIST,
1.0e-6, 1.0 - 1.0e-6};
- ConversionData conv_data = {writer, tol, convert_primitives, *dbip,
std::set<std::string>()};
+ ConversionData conv_data(writer, tol, *dbip);
{
model *vmodel;
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