Revision: 76396
http://sourceforge.net/p/brlcad/code/76396
Author: starseeker
Date: 2020-07-21 19:08:41 +0000 (Tue, 21 Jul 2020)
Log Message:
-----------
Consolidate bot related commands into one plugin
Modified Paths:
--------------
brlcad/branches/gedplugins/src/libged/CMakeLists.txt
brlcad/branches/gedplugins/src/libged/bot/bot.cpp
Added Paths:
-----------
brlcad/branches/gedplugins/src/libged/bot/bot_condense.c
brlcad/branches/gedplugins/src/libged/bot/bot_decimate.c
brlcad/branches/gedplugins/src/libged/bot/bot_dump.c
brlcad/branches/gedplugins/src/libged/bot/bot_face_fuse.c
brlcad/branches/gedplugins/src/libged/bot/bot_face_sort.c
brlcad/branches/gedplugins/src/libged/bot/bot_flip.c
brlcad/branches/gedplugins/src/libged/bot/bot_fuse.c
brlcad/branches/gedplugins/src/libged/bot/bot_merge.c
brlcad/branches/gedplugins/src/libged/bot/bot_smooth.c
brlcad/branches/gedplugins/src/libged/bot/bot_split.c
brlcad/branches/gedplugins/src/libged/bot/bot_sync.c
brlcad/branches/gedplugins/src/libged/bot/bot_vertex_fuse.c
Removed Paths:
-------------
brlcad/branches/gedplugins/src/libged/bot_condense/
brlcad/branches/gedplugins/src/libged/bot_decimate/
brlcad/branches/gedplugins/src/libged/bot_dump/
brlcad/branches/gedplugins/src/libged/bot_face_fuse/
brlcad/branches/gedplugins/src/libged/bot_face_sort/
brlcad/branches/gedplugins/src/libged/bot_flip/
brlcad/branches/gedplugins/src/libged/bot_fuse/
brlcad/branches/gedplugins/src/libged/bot_merge/
brlcad/branches/gedplugins/src/libged/bot_smooth/
brlcad/branches/gedplugins/src/libged/bot_split/
brlcad/branches/gedplugins/src/libged/bot_sync/
brlcad/branches/gedplugins/src/libged/bot_vertex_fuse/
Modified: brlcad/branches/gedplugins/src/libged/CMakeLists.txt
===================================================================
--- brlcad/branches/gedplugins/src/libged/CMakeLists.txt 2020-07-21
18:53:10 UTC (rev 76395)
+++ brlcad/branches/gedplugins/src/libged/CMakeLists.txt 2020-07-21
19:08:41 UTC (rev 76396)
@@ -95,18 +95,18 @@
bot/check.cpp
bot/extrude.cpp
bot/remesh.cpp
- bot_condense/bot_condense.c
- bot_decimate/bot_decimate.c
- bot_dump/bot_dump.c
- bot_face_fuse/bot_face_fuse.c
- bot_face_sort/bot_face_sort.c
- bot_flip/bot_flip.c
- bot_fuse/bot_fuse.c
- bot_merge/bot_merge.c
- bot_smooth/bot_smooth.c
- bot_split/bot_split.c
- bot_sync/bot_sync.c
- bot_vertex_fuse/bot_vertex_fuse.c
+ bot/bot_condense.c
+ bot/bot_decimate.c
+ bot/bot_dump.c
+ bot/bot_face_fuse.c
+ bot/bot_face_sort.c
+ bot/bot_flip.c
+ bot/bot_fuse.c
+ bot/bot_merge.c
+ bot/bot_smooth.c
+ bot/bot_split.c
+ bot/bot_sync.c
+ bot/bot_vertex_fuse.c
brep/brep.cpp
brep/conversion.cpp
brep/csg.cpp
@@ -469,18 +469,6 @@
add_subdirectory(blast)
add_subdirectory(bo)
add_subdirectory(bot)
-add_subdirectory(bot_condense)
-add_subdirectory(bot_decimate)
-add_subdirectory(bot_dump)
-add_subdirectory(bot_face_fuse)
-add_subdirectory(bot_face_sort)
-add_subdirectory(bot_flip)
-add_subdirectory(bot_fuse)
-add_subdirectory(bot_merge)
-add_subdirectory(bot_smooth)
-add_subdirectory(bot_split)
-add_subdirectory(bot_sync)
-add_subdirectory(bot_vertex_fuse)
add_subdirectory(brep)
add_subdirectory(cat)
add_subdirectory(cc)
Modified: brlcad/branches/gedplugins/src/libged/bot/bot.cpp
===================================================================
--- brlcad/branches/gedplugins/src/libged/bot/bot.cpp 2020-07-21 18:53:10 UTC
(rev 76395)
+++ brlcad/branches/gedplugins/src/libged/bot/bot.cpp 2020-07-21 19:08:41 UTC
(rev 76396)
@@ -440,10 +440,62 @@
extern "C" {
struct ged_cmd_impl bot_cmd_impl = { "bot", ged_bot, GED_CMD_DEFAULT };
const struct ged_cmd bot_cmd = { &bot_cmd_impl };
- const struct ged_cmd *bot_cmds[] = { &bot_cmd, NULL };
- static const struct ged_plugin pinfo = { bot_cmds, 1 };
+ struct ged_cmd_impl bot_condense_cmd_impl = {"bot_condense",
ged_bot_condense, GED_CMD_DEFAULT};
+ const struct ged_cmd bot_condense_cmd = { &bot_condense_cmd_impl };
+ struct ged_cmd_impl bot_decimate_cmd_impl = {"bot_decimate",
ged_bot_decimate, GED_CMD_DEFAULT};
+ const struct ged_cmd bot_decimate_cmd = { &bot_decimate_cmd_impl };
+
+ struct ged_cmd_impl bot_dump_cmd_impl = {"bot_dump", ged_bot_dump,
GED_CMD_DEFAULT};
+ const struct ged_cmd bot_dump_cmd = { &bot_dump_cmd_impl };
+
+ struct ged_cmd_impl bot_face_fuse_cmd_impl = {"bot_face_fuse",
ged_bot_face_fuse, GED_CMD_DEFAULT};
+ const struct ged_cmd bot_face_fuse_cmd = { &bot_face_fuse_cmd_impl };
+
+ struct ged_cmd_impl bot_face_sort_cmd_impl = {"bot_face_sort",
ged_bot_face_sort, GED_CMD_DEFAULT};
+ const struct ged_cmd bot_face_sort_cmd = { &bot_face_sort_cmd_impl };
+
+ struct ged_cmd_impl bot_flip_cmd_impl = {"bot_flip", ged_bot_flip,
GED_CMD_DEFAULT};
+ const struct ged_cmd bot_flip_cmd = { &bot_flip_cmd_impl };
+
+ struct ged_cmd_impl bot_fuse_cmd_impl = {"bot_fuse", ged_bot_fuse,
GED_CMD_DEFAULT};
+ const struct ged_cmd bot_fuse_cmd = { &bot_fuse_cmd_impl };
+
+ struct ged_cmd_impl bot_merge_cmd_impl = {"bot_merge", ged_bot_merge,
GED_CMD_DEFAULT};
+ const struct ged_cmd bot_merge_cmd = { &bot_merge_cmd_impl };
+
+ struct ged_cmd_impl bot_smooth_cmd_impl = {"bot_smooth", ged_bot_smooth,
GED_CMD_DEFAULT};
+ const struct ged_cmd bot_smooth_cmd = { &bot_smooth_cmd_impl };
+
+ struct ged_cmd_impl bot_split_cmd_impl = {"bot_split", ged_bot_split,
GED_CMD_DEFAULT};
+ const struct ged_cmd bot_split_cmd = { &bot_split_cmd_impl };
+
+ struct ged_cmd_impl bot_sync_cmd_impl = {"bot_sync", ged_bot_sync,
GED_CMD_DEFAULT};
+ const struct ged_cmd bot_sync_cmd = { &bot_sync_cmd_impl };
+
+ struct ged_cmd_impl bot_vertex_fuse_cmd_impl = {"bot_vertex_fuse",
ged_bot_vertex_fuse, GED_CMD_DEFAULT};
+ const struct ged_cmd bot_vertex_fuse_cmd = { &bot_vertex_fuse_cmd_impl };
+
+ const struct ged_cmd *bot_cmds[] = {
+ &bot_cmd,
+ &bot_condense_cmd,
+ &bot_decimate_cmd,
+ &bot_dump_cmd,
+ &bot_face_fuse_cmd,
+ &bot_face_sort_cmd,
+ &bot_flip_cmd,
+ &bot_fuse_cmd,
+ &bot_merge_cmd,
+ &bot_smooth_cmd,
+ &bot_split_cmd,
+ &bot_sync_cmd,
+ &bot_vertex_fuse_cmd,
+ NULL
+ };
+
+ static const struct ged_plugin pinfo = { bot_cmds, 13 };
+
COMPILER_DLLEXPORT const struct ged_plugin *ged_plugin_info()
{
return &pinfo;
Copied: brlcad/branches/gedplugins/src/libged/bot/bot_condense.c (from rev
76395, brlcad/branches/gedplugins/src/libged/bot_condense/bot_condense.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/bot/bot_condense.c
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/bot/bot_condense.c 2020-07-21
19:08:41 UTC (rev 76396)
@@ -0,0 +1,92 @@
+/* B O T _ C O N D E N S E . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2008-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file libged/bot_condense.c
+ *
+ * The bot_condense command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "rt/geom.h"
+
+#include "../ged_private.h"
+
+
+int
+ged_bot_condense(struct ged *gedp, int argc, const char *argv[])
+{
+ struct directory *old_dp, *new_dp;
+ struct rt_db_internal intern;
+ struct rt_bot_internal *bot;
+ int count2=0;
+ static const char *usage = "new_bot old_bot";
+
+ GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+ GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+ GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+ /* initialize result */
+ bu_vls_trunc(gedp->ged_result_str, 0);
+
+ /* must be wanting help */
+ if (argc == 1) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_HELP;
+ }
+
+ if (argc != 3) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_ERROR;
+ }
+
+ GED_DB_LOOKUP(gedp, old_dp, argv[2], LOOKUP_NOISY, GED_ERROR & GED_QUIET);
+ GED_DB_GET_INTERNAL(gedp, &intern, old_dp, bn_mat_identity,
&rt_uniresource, GED_ERROR);
+
+ if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || intern.idb_minor_type
!= DB5_MINORTYPE_BRLCAD_BOT) {
+ bu_vls_printf(gedp->ged_result_str, "%s: %s is not a BOT solid!\n",
argv[0], argv[2]);
+ return GED_ERROR;
+ }
+
+ bot = (struct rt_bot_internal *)intern.idb_ptr;
+ RT_BOT_CK_MAGIC(bot);
+
+ count2 = rt_bot_condense(bot);
+ bu_vls_printf(gedp->ged_result_str, "%s: %d dead vertices eliminated\n",
argv[0], count2);
+
+ GED_DB_DIRADD(gedp, new_dp, argv[1], RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID,
(void *)&intern.idb_type, GED_ERROR);
+ GED_DB_PUT_INTERNAL(gedp, new_dp, &intern, &rt_uniresource, GED_ERROR);
+
+ return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Copied: brlcad/branches/gedplugins/src/libged/bot/bot_decimate.c (from rev
76395, brlcad/branches/gedplugins/src/libged/bot_decimate/bot_decimate.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/bot/bot_decimate.c
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/bot/bot_decimate.c 2020-07-21
19:08:41 UTC (rev 76396)
@@ -0,0 +1,201 @@
+/* B O T _ D E C I M A T E . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2008-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file libged/bot_decimate.c
+ *
+ * The bot_decimate command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "bu/getopt.h"
+#include "rt/geom.h"
+#include "ged.h"
+
+
+int
+ged_bot_decimate(struct ged *gedp, int argc, const char *argv[])
+{
+ int c;
+ struct rt_db_internal intern;
+ struct rt_bot_internal *bot;
+ struct directory *dp;
+ fastf_t max_chord_error = -1.0;
+ fastf_t max_normal_error = -1.0;
+ fastf_t min_edge_length = -1.0;
+ fastf_t feature_size = -1.0;
+ static const char *usage = "-f feature_size (to use the newer GCT
decimator)"
+ "\nOR: -c maximum_chord_error -n
maximum_normal_error -e minimum_edge_length new_bot_name current_bot_name";
+
+ GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+ GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+ GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+ /* initialize result */
+ bu_vls_trunc(gedp->ged_result_str, 0);
+
+ /* must be wanting help */
+ if (argc == 1) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_HELP;
+ }
+
+ if (argc < 5 || argc > 9) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_ERROR;
+ }
+
+ /* process args */
+ bu_optind = 1;
+ bu_opterr = 0;
+
+ while ((c = bu_getopt(argc, (char * const *)argv, "c:n:e:f:")) != -1) {
+ switch (c) {
+ case 'c':
+ max_chord_error = atof(bu_optarg);
+
+ if (max_chord_error < 0.0) {
+ bu_vls_printf(gedp->ged_result_str,
+ "Maximum chord error cannot be less than
zero");
+ return GED_ERROR;
+ }
+
+ break;
+
+ case 'n':
+ max_normal_error = atof(bu_optarg);
+
+ if (max_normal_error < 0.0) {
+ bu_vls_printf(gedp->ged_result_str,
+ "Maximum normal error cannot be less than
zero");
+ return GED_ERROR;
+ }
+
+ break;
+
+ case 'e':
+ min_edge_length = atof(bu_optarg);
+
+ if (min_edge_length < 0.0) {
+ bu_vls_printf(gedp->ged_result_str,
+ "minimum edge length cannot be less than
zero");
+ return GED_ERROR;
+ }
+
+ break;
+
+ case 'f':
+ feature_size = atof(bu_optarg);
+
+ if (feature_size < 0.0) {
+ bu_vls_printf(gedp->ged_result_str,
+ "minimum feature size cannot be less than
zero");
+ return GED_ERROR;
+ }
+
+ break;
+
+ default: {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0],
usage);
+ return GED_ERROR;
+ }
+ }
+ }
+
+ if (feature_size >= 0.0 && (max_chord_error >= 0.0 || max_normal_error >=
0.0 || min_edge_length >= 0.0)) {
+ bu_vls_printf(gedp->ged_result_str, "-f may not be used with -c, -n, or
-e");
+ return GED_ERROR;
+ }
+
+ argc -= bu_optind;
+ argv += bu_optind;
+
+ /* make sure new solid does not already exist */
+ GED_CHECK_EXISTS(gedp, argv[0], LOOKUP_QUIET, GED_ERROR);
+
+ /* make sure current solid does exist */
+ GED_DB_LOOKUP(gedp, dp, argv[1], LOOKUP_QUIET, GED_ERROR);
+
+ /* import the current solid */
+ RT_DB_INTERNAL_INIT(&intern);
+ GED_DB_GET_INTERNAL(gedp, &intern, dp, NULL, gedp->ged_wdbp->wdb_resp,
GED_ERROR);
+
+ /* make sure this is a BOT solid */
+ if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || intern.idb_minor_type
!= DB5_MINORTYPE_BRLCAD_BOT) {
+ bu_vls_printf(gedp->ged_result_str, "%s is not a BOT solid\n", argv[1]);
+ rt_db_free_internal(&intern);
+ return GED_ERROR;
+ }
+
+ bot = (struct rt_bot_internal *)intern.idb_ptr;
+
+ RT_BOT_CK_MAGIC(bot);
+
+ /* convert maximum error, edge length, and feature size to mm */
+ if (max_chord_error > 0.0) {
+ max_chord_error = max_chord_error *
gedp->ged_wdbp->dbip->dbi_local2base;
+ }
+
+ if (min_edge_length > 0.0) {
+ min_edge_length = min_edge_length *
gedp->ged_wdbp->dbip->dbi_local2base;
+ }
+
+ if (feature_size >= 0.0) {
+ /* use the new GCT decimator */
+ const size_t orig_num_faces = bot->num_faces;
+ size_t edges_removed;
+ feature_size *= gedp->ged_wdbp->dbip->dbi_local2base;
+ edges_removed = rt_bot_decimate_gct(bot, feature_size);
+ bu_log("original face count = %zu\n", orig_num_faces);
+ bu_log("\tedges removed = %zu\n", edges_removed);
+ bu_log("\tnew face count = %zu\n", bot->num_faces);
+ } else {
+ /* use the old decimator */
+ if (rt_bot_decimate(bot, max_chord_error, max_normal_error,
min_edge_length) < 0) {
+ bu_vls_printf(gedp->ged_result_str, "Decimation Error\n");
+ rt_db_free_internal(&intern);
+ return GED_ERROR;
+ }
+ }
+
+ /* save the result to the database */
+ /* XXX - should this be rt_db_put_internal() instead? */
+ if (wdb_put_internal(gedp->ged_wdbp, argv[0], &intern, 1.0) < 0) {
+ bu_vls_printf(gedp->ged_result_str,
+ "Failed to write decimated BOT back to database\n");
+ return GED_ERROR;
+ }
+
+ return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Copied: brlcad/branches/gedplugins/src/libged/bot/bot_dump.c (from rev 76395,
brlcad/branches/gedplugins/src/libged/bot_dump/bot_dump.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/bot/bot_dump.c
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/bot/bot_dump.c 2020-07-21
19:08:41 UTC (rev 76396)
@@ -0,0 +1,1566 @@
+/* B O T _ D U M P . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2008-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file libged/bot_dump.c
+ *
+ * The bot_dump command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <ctype.h>
+#include "bio.h"
+#include "bnetwork.h"
+
+#include "bu/cv.h"
+#include "bu/getopt.h"
+#include "bu/units.h"
+#include "vmath.h"
+#include "nmg.h"
+#include "rt/geom.h"
+
+#include "raytrace.h"
+#include "wdb.h"
+
+#include "brlcad_version.h"
+
+#include "raytrace.h"
+
+#include "dm/bview.h"
+#include "dm.h"
+
+#include "../ged_private.h"
+
+
+#define V3ARGS_SCALE(_a) (_a)[X]*cfactor, (_a)[Y]*cfactor, (_a)[Z]*cfactor
+
+static char usage[] = "[-b] [-n] [-m directory] [-o file] [-t dxf|obj|sat|stl]
[-u units] [bot1 bot2 ...]";
+
+
+struct _ged_bot_dump_client_data {
+ struct ged *gedp;
+ FILE *fp;
+ int fd;
+ char *file_ext;
+};
+
+
+struct _ged_obj_material {
+ struct bu_list l;
+ struct bu_vls name;
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+ fastf_t a;
+};
+
+
+static int using_dbot_dump;
+struct bu_list HeadObjMaterials = BU_LIST_INIT_ZERO;
+struct bu_vls obj_materials_file = BU_VLS_INIT_ZERO;
+FILE *obj_materials_fp;
+int num_obj_materials;
+int curr_obj_red;
+int curr_obj_green;
+int curr_obj_blue;
+fastf_t curr_obj_alpha;
+
+static enum otype output_type;
+static int binary;
+static int normals;
+static fastf_t cfactor;
+static char *output_file; /* output filename */
+static char *output_directory; /* directory name to hold output files */
+static unsigned int total_faces;
+static int v_offset;
+static int curr_line_num;
+
+static int curr_body_id;
+static int curr_lump_id;
+static int curr_shell_id;
+static int curr_face_id;
+static int curr_loop_id;
+static int curr_edge_id;
+
+/* Byte swaps a four byte value */
+static void
+lswap(unsigned int *v)
+{
+ unsigned int r;
+
+ r =*v;
+ *v = ((r & 0xff) << 24) | ((r & 0xff00) << 8) | ((r & 0xff0000) >> 8)
+ | ((r & 0xff000000) >> 24);
+}
+
+
+static struct _ged_obj_material *
+obj_get_material(int red, int green, int blue, fastf_t transparency)
+{
+ struct _ged_obj_material *gomp;
+
+ for (BU_LIST_FOR(gomp, _ged_obj_material, &HeadObjMaterials)) {
+ if (gomp->r == red &&
+ gomp->g == green &&
+ gomp->b == blue &&
+ ZERO(gomp->a - transparency)) {
+ return gomp;
+ }
+ }
+
+ BU_GET(gomp, struct _ged_obj_material);
+ BU_LIST_APPEND(&HeadObjMaterials, &gomp->l);
+ gomp->r = red;
+ gomp->g = green;
+ gomp->b = blue;
+ gomp->a = transparency;
+ bu_vls_init(&gomp->name);
+ bu_vls_printf(&gomp->name, "matl_%d", ++num_obj_materials);
+
+ /* Write out newmtl to mtl file */
+ fprintf(obj_materials_fp, "newmtl %s\n", bu_vls_addr(&gomp->name));
+ fprintf(obj_materials_fp, "Kd %f %f %f\n",
+ (fastf_t)gomp->r / 255.0,
+ (fastf_t)gomp->g / 255.0,
+ (fastf_t)gomp->b / 255.0);
+ fprintf(obj_materials_fp, "d %f\n", gomp->a);
+ fprintf(obj_materials_fp, "illum 1\n");
+
+ return gomp;
+}
+
+
+static void
+obj_free_materials() {
+ struct _ged_obj_material *gomp;
+
+ while (BU_LIST_WHILE(gomp, _ged_obj_material, &HeadObjMaterials)) {
+ BU_LIST_DEQUEUE(&gomp->l);
+ bu_vls_free(&gomp->name);
+ BU_PUT(gomp, struct _ged_obj_material);
+ }
+}
+
+
+static void
+sat_write_header(FILE *fp)
+{
+ time_t now;
+
+ /* SAT header consists of three lines:
+ *
+ * 1: SAT_version num_records num_objects history_boolean
+ * 2: strlen product_id_str strlen version_str strlen date_str
+ * 3: cnv_to_mm resabs_value resnor_value
+ *
+ * When num_records is zero, it looks for an end marker.
+ */
+ fprintf(fp, "400 0 1 0\n");
+
+ time(&now);
+ fprintf(fp, "%ld BRL-CAD(%s)-bot_dump 16 ACIS 8.0 Unknown %ld %s",
+ (long)strlen(brlcad_version())+18, brlcad_version(),
(long)strlen(ctime(&now)) - 1, ctime(&now));
+
+ /* FIXME: this includes abs tolerance info, should probably output ours */
+ fprintf(fp, "1 9.9999999999999995e-007 1e-010\n");
+}
+
+
+static void
+sat_write_bot(struct rt_bot_internal *bot, FILE *fp, char *UNUSED(name))
+{
+ int i, j;
+ fastf_t *vertices;
+ int *faces;
+ int first_vertex;
+ int first_coedge;
+ int first_face;
+ int num_vertices = bot->num_vertices;
+ int num_faces = bot->num_faces;
+
+ vertices = bot->vertices;
+ faces = bot->faces;
+
+ curr_body_id = curr_line_num;
+ curr_lump_id = curr_body_id + 1;
+ curr_shell_id = curr_lump_id + 1;
+ curr_face_id = curr_shell_id + 1 + num_vertices*2 + num_faces*6;
+
+ fprintf(fp, "-%d body $-1 $%d $-1 $-1 #\n", curr_body_id, curr_lump_id);
+ fprintf(fp, "-%d lump $-1 $-1 $%d $%d #\n", curr_lump_id, curr_shell_id,
curr_body_id);
+ fprintf(fp, "-%d shell $-1 $-1 $-1 $%d $-1 $%d #\n", curr_shell_id,
curr_face_id, curr_lump_id);
+
+ curr_line_num += 3;
+
+ /* Dump out vertices */
+ first_vertex = curr_line_num;
+ for (i = 0; i < num_vertices; i++) {
+ curr_edge_id = -1;
+ for (j = 0; j < num_faces; j++) {
+ if (faces[3*j]+first_vertex == curr_line_num) {
+ curr_edge_id = first_vertex + num_vertices*2 + num_faces*3 +
j*3;
+ break;
+ } else if (faces[3*j+1]+first_vertex == curr_line_num) {
+ curr_edge_id = first_vertex + num_vertices*2 + num_faces*3 +
j*3 + 1;
+ break;
+ } else if (faces[3*j+2]+first_vertex == curr_line_num) {
+ curr_edge_id = first_vertex + num_vertices*2 + num_faces*3 +
j*3 + 2;
+ break;
+ }
+ }
+
+ fprintf(fp, "-%d vertex $-1 $%d $%d #\n", curr_line_num, curr_edge_id,
curr_line_num+num_vertices);
+ ++curr_line_num;
+ }
+
+ /* Dump out points */
+ for (i = 0; i < num_vertices; i++) {
+ fprintf(fp, "-%d point $-1 %f %f %f #\n", curr_line_num,
V3ARGS_SCALE(&vertices[3*i]));
+ ++curr_line_num;
+ }
+
+ /* Dump out coedges */
+ first_coedge = curr_line_num;
+ curr_loop_id = first_coedge+num_faces*7;
+ for (i = 0; i < num_faces; i++) {
+ fprintf(fp, "-%d coedge $-1 $%d $%d $%d $%d forward $%d $-1 #\n",
+ curr_line_num, curr_line_num+1, curr_line_num+2, curr_line_num,
+ curr_line_num+num_faces*3, curr_loop_id);
+ ++curr_line_num;
+ fprintf(fp, "-%d coedge $-1 $%d $%d $%d $%d forward $%d $-1 #\n",
+ curr_line_num, curr_line_num+1, curr_line_num-1, curr_line_num,
+ curr_line_num+num_faces*3, curr_loop_id);
+ ++curr_line_num;
+ fprintf(fp, "-%d coedge $-1 $%d $%d $%d $%d forward $%d $-1 #\n",
+ curr_line_num, curr_line_num-2, curr_line_num-1, curr_line_num,
+ curr_line_num+num_faces*3, curr_loop_id);
+ ++curr_line_num;
+ ++curr_loop_id;
+ }
+
+ /* Dump out edges */
+ for (i = 0; i < num_faces; i++) {
+ fprintf(fp, "-%d edge $-1 $%d $%d $%d $%d forward #\n", curr_line_num,
+ faces[3*i]+first_vertex, faces[3*i+1]+first_vertex,
+ first_coedge + i*3, curr_line_num + num_faces*5);
+ ++curr_line_num;
+ fprintf(fp, "-%d edge $-1 $%d $%d $%d $%d forward #\n", curr_line_num,
+ faces[3*i+1]+first_vertex, faces[3*i+2]+first_vertex,
+ first_coedge + i*3 + 1, curr_line_num + num_faces*5);
+ ++curr_line_num;
+ fprintf(fp, "-%d edge $-1 $%d $%d $%d $%d forward #\n", curr_line_num,
+ faces[3*i+2]+first_vertex, faces[3*i]+first_vertex,
+ first_coedge + i*3 + 2, curr_line_num + num_faces*5);
+ ++curr_line_num;
+ }
+
+ /* Dump out faces */
+ first_face = curr_line_num;
+ for (i = 0; i < num_faces-1; i++) {
+ fprintf(fp, "-%d face $-1 $%d $%d $%d $-1 $%d forward single #\n",
+ curr_line_num, curr_line_num+1, curr_line_num+num_faces,
+ curr_shell_id, curr_line_num + num_faces*5);
+ ++curr_line_num;
+ }
+ fprintf(fp, "-%d face $-1 $-1 $%d $%d $-1 $%d forward single #\n",
+ curr_line_num, curr_line_num+num_faces, curr_shell_id,
+ curr_line_num + num_faces*5);
+ ++curr_line_num;
+
+ /* Dump out loops */
+ for (i = 0; i < num_faces; i++) {
+ fprintf(fp, "-%d loop $-1 $-1 $%d $%d #\n",
+ curr_line_num, first_coedge+i*3, first_face+i);
+ ++curr_line_num;
+ }
+
+ /* Dump out straight-curves for each edge */
+ for (i = 0; i < num_faces; i++) {
+ point_t A;
+ point_t B;
+ point_t C;
+ vect_t BmA;
+ vect_t CmB;
+ vect_t AmC;
+ int vi;
+
+ vi = 3*faces[3*i];
+ VSET(A, vertices[vi], vertices[vi+1], vertices[vi+2]);
+ vi = 3*faces[3*i+1];
+ VSET(B, vertices[vi], vertices[vi+1], vertices[vi+2]);
+ vi = 3*faces[3*i+2];
+ VSET(C, vertices[vi], vertices[vi+1], vertices[vi+2]);
+ VSUB2(BmA, B, A);
+ VSUB2(CmB, C, B);
+ VSUB2(AmC, A, C);
+ VUNITIZE(BmA);
+ VUNITIZE(CmB);
+ VUNITIZE(AmC);
+
+ fprintf(fp, "-%d straight-curve $-1 %f %f %f %f %f %f I I #\n",
curr_line_num, V3ARGS_SCALE(A), V3ARGS(BmA));
+ ++curr_line_num;
+ fprintf(fp, "-%d straight-curve $-1 %f %f %f %f %f %f I I #\n",
curr_line_num, V3ARGS_SCALE(B), V3ARGS(CmB));
+ ++curr_line_num;
+ fprintf(fp, "-%d straight-curve $-1 %f %f %f %f %f %f I I #\n",
curr_line_num, V3ARGS_SCALE(C), V3ARGS(AmC));
+ ++curr_line_num;
+ }
+
+ /* Dump out plane-surfaces for each face */
+ for (i = 0; i < num_faces; i++) {
+ point_t A;
+ point_t B;
+ point_t C;
+ point_t center;
+ vect_t BmA;
+ vect_t CmA;
+ vect_t norm;
+ int vi;
+ fastf_t sf = 1.0/3.0;
+
+ vi = 3*faces[3*i];
+ VSET(A, vertices[vi], vertices[vi+1], vertices[vi+2]);
+ vi = 3*faces[3*i+1];
+ VSET(B, vertices[vi], vertices[vi+1], vertices[vi+2]);
+ vi = 3*faces[3*i+2];
+ VSET(C, vertices[vi], vertices[vi+1], vertices[vi+2]);
+
+ VADD3(center, A, B, C);
+ VSCALE(center, center, sf);
+
+ VSUB2(BmA, B, A);
+ VSUB2(CmA, C, A);
+ if (bot->orientation != RT_BOT_CW) {
+ VCROSS(norm, BmA, CmA);
+ } else {
+ VCROSS(norm, CmA, BmA);
+ }
+ VUNITIZE(norm);
+
+ VUNITIZE(BmA);
+
+ fprintf(fp, "-%d plane-surface $-1 %f %f %f %f %f %f %f %f %f forward_v
I I I I #\n",
+ curr_line_num, V3ARGS_SCALE(A), V3ARGS(norm), V3ARGS(BmA));
+
+ ++curr_line_num;
+ }
+}
+
+
+static void
+dxf_write_bot(struct rt_bot_internal *bot, FILE *fp, char *name)
+{
+ fastf_t *vertices;
+ int num_faces, *faces;
+ point_t A;
+ point_t B;
+ point_t C;
+ int i, vi;
+
+ vertices = bot->vertices;
+ num_faces = bot->num_faces;
+ faces = bot->faces;
+
+ for (i = 0; i < num_faces; i++) {
+ vi = 3*faces[3*i];
+ VSET(A, vertices[vi], vertices[vi+1], vertices[vi+2]);
+ vi = 3*faces[3*i+1];
+ VSET(B, vertices[vi], vertices[vi+1], vertices[vi+2]);
+ vi = 3*faces[3*i+2];
+ VSET(C, vertices[vi], vertices[vi+1], vertices[vi+2]);
+
+ VSCALE(A, A, cfactor);
+ VSCALE(B, B, cfactor);
+ VSCALE(C, C, cfactor);
+
+ fprintf(fp, "0\n3DFACE\n8\n%s\n62\n7\n", name);
+ fprintf(fp, "%d\n%f\n%d\n%f\n%d\n%f\n",
+ 10, A[X], 20, A[Y], 30, A[Z]);
+ fprintf(fp, "%d\n%f\n%d\n%f\n%d\n%f\n",
+ 11, B[X], 21, B[Y], 31, B[Z]);
+ fprintf(fp, "%d\n%f\n%d\n%f\n%d\n%f\n",
+ 12, C[X], 22, C[Y], 32, C[Z]);
+ fprintf(fp, "%d\n%f\n%d\n%f\n%d\n%f\n",
+ 12, C[X], 22, C[Y], 32, C[Z]);
+ }
+
+}
+
+
+static void
+obj_write_bot(struct rt_bot_internal *bot, FILE *fp, char *name)
+{
+ int num_vertices;
+ fastf_t *vertices;
+ int num_faces, *faces;
+ point_t A;
+ point_t B;
+ point_t C;
+ vect_t BmA;
+ vect_t CmA;
+ vect_t norm;
+ int i, vi;
+ struct _ged_obj_material *gomp;
+
+ if (using_dbot_dump) {
+ gomp = obj_get_material(curr_obj_red,
+ curr_obj_green,
+ curr_obj_blue,
+ curr_obj_alpha);
+ fprintf(fp, "usemtl %s\n", bu_vls_addr(&gomp->name));
+ }
+
+ num_vertices = bot->num_vertices;
+ vertices = bot->vertices;
+ num_faces = bot->num_faces;
+ faces = bot->faces;
+
+ fprintf(fp, "g %s\n", name);
+
+ for (i = 0; i < num_vertices; i++) {
+ fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(&vertices[3*i]));
+ }
+
+ if (normals) {
+ for (i = 0; i < num_faces; i++) {
+ vi = 3*faces[3*i];
+ VSET(A, vertices[vi], vertices[vi+1], vertices[vi+2]);
+ vi = 3*faces[3*i+1];
+ VSET(B, vertices[vi], vertices[vi+1], vertices[vi+2]);
+ vi = 3*faces[3*i+2];
+ VSET(C, vertices[vi], vertices[vi+1], vertices[vi+2]);
+
+ VSUB2(BmA, B, A);
+ VSUB2(CmA, C, A);
+ if (bot->orientation != RT_BOT_CW) {
+ VCROSS(norm, BmA, CmA);
+ } else {
+ VCROSS(norm, CmA, BmA);
+ }
+ VUNITIZE(norm);
+
+ fprintf(fp, "vn %f %f %f\n", V3ARGS(norm));
+ }
+ }
+
+ if (normals) {
+ for (i = 0; i < num_faces; i++) {
+ fprintf(fp, "f %d//%d %d//%d %d//%d\n", faces[3*i]+v_offset, i+1,
faces[3*i+1]+v_offset, i+1, faces[3*i+2]+v_offset, i+1);
+ }
+ } else {
+ for (i = 0; i < num_faces; i++) {
+ fprintf(fp, "f %d %d %d\n", faces[3*i]+v_offset,
faces[3*i+1]+v_offset, faces[3*i+2]+v_offset);
+ }
+ }
+
+ v_offset += num_vertices;
+}
+
+
+static void
+stl_write_bot(struct rt_bot_internal *bot, FILE *fp, char *name)
+{
+ fastf_t *vertices;
+ int num_faces, *faces;
+ point_t A;
+ point_t B;
+ point_t C;
+ vect_t BmA;
+ vect_t CmA;
+ vect_t norm;
+ int i, vi;
+
+ vertices = bot->vertices;
+ num_faces = bot->num_faces;
+ faces = bot->faces;
+
+ fprintf(fp, "solid %s\n", name);
+ for (i = 0; i < num_faces; i++) {
+ vi = 3*faces[3*i];
+ VSET(A, vertices[vi], vertices[vi+1], vertices[vi+2]);
+ vi = 3*faces[3*i+1];
+ VSET(B, vertices[vi], vertices[vi+1], vertices[vi+2]);
+ vi = 3*faces[3*i+2];
+ VSET(C, vertices[vi], vertices[vi+1], vertices[vi+2]);
+
+ VSUB2(BmA, B, A);
+ VSUB2(CmA, C, A);
+ if (bot->orientation != RT_BOT_CW) {
+ VCROSS(norm, BmA, CmA);
+ } else {
+ VCROSS(norm, CmA, BmA);
+ }
+ VUNITIZE(norm);
+
+ fprintf(fp, " facet normal %f %f %f\n", V3ARGS(norm));
+ fprintf(fp, " outer loop\n");
+ fprintf(fp, " vertex %f %f %f\n", V3ARGS_SCALE(A));
+ fprintf(fp, " vertex %f %f %f\n", V3ARGS_SCALE(B));
+ fprintf(fp, " vertex %f %f %f\n", V3ARGS_SCALE(C));
+ fprintf(fp, " endloop\n");
+ fprintf(fp, " endfacet\n");
+ }
+ fprintf(fp, "endsolid %s\n", name);
+}
+
+
+static void
+stl_write_bot_binary(struct rt_bot_internal *bot, int fd, char *UNUSED(name))
+{
+ fastf_t *vertices;
+ size_t num_faces;
+ int *faces;
+ point_t A;
+ point_t B;
+ point_t C;
+ vect_t BmA;
+ vect_t CmA;
+ vect_t norm;
+ unsigned long i, j, vi;
+
+ vertices = bot->vertices;
+ num_faces = bot->num_faces;
+ faces = bot->faces;
+
+ /* Write out the vertex data for each triangle */
+ for (i = 0; (size_t)i < num_faces; i++) {
+ float flts[12];
+ float *flt_ptr;
+ unsigned char vert_buffer[50];
+ int ret;
+
+ vi = 3*faces[3*i];
+ VSET(A, vertices[vi], vertices[vi+1], vertices[vi+2]);
+ vi = 3*faces[3*i+1];
+ VSET(B, vertices[vi], vertices[vi+1], vertices[vi+2]);
+ vi = 3*faces[3*i+2];
+ VSET(C, vertices[vi], vertices[vi+1], vertices[vi+2]);
+
+ VSUB2(BmA, B, A);
+ VSUB2(CmA, C, A);
+ if (bot->orientation != RT_BOT_CW) {
+ VCROSS(norm, BmA, CmA);
+ } else {
+ VCROSS(norm, CmA, BmA);
+ }
+ VUNITIZE(norm);
+
+ VSCALE(A, A, cfactor);
+ VSCALE(B, B, cfactor);
+ VSCALE(C, C, cfactor);
+
+ memset(vert_buffer, 0, sizeof(vert_buffer));
+
+ flt_ptr = flts;
+ VMOVE(flt_ptr, norm);
+ flt_ptr += 3;
+ VMOVE(flt_ptr, A);
+ flt_ptr += 3;
+ VMOVE(flt_ptr, B);
+ flt_ptr += 3;
+ VMOVE(flt_ptr, C);
+ flt_ptr += 3;
+
+ bu_cv_htonf(vert_buffer, (const unsigned char *)flts, 12);
+ for (j = 0; j < 12; j++) {
+ lswap((unsigned int *)&vert_buffer[j*4]);
+ }
+ ret = write(fd, vert_buffer, 50);
+ if (ret < 0) {
+ perror("write");
+ }
+ }
+}
+
+
+void
+_ged_bot_dump(struct directory *dp, const struct db_full_path *pathp, struct
rt_bot_internal *bot, FILE *fp, int fd, const char *file_ext, const char
*db_g_name)
+{
+ int ret;
+
+ if (output_directory) {
+ char *cp;
+ struct bu_vls file_name = BU_VLS_INIT_ZERO;
+
+ bu_vls_strcpy(&file_name, output_directory);
+ bu_vls_putc(&file_name, '/');
+ cp = dp->d_namep;
+ while (*cp != '\0') {
+ if (*cp == '/') {
+ bu_vls_putc(&file_name, '@');
+ } else if (*cp == '.' || isspace((int)*cp)) {
+ bu_vls_putc(&file_name, '_');
+ } else {
+ bu_vls_putc(&file_name, *cp);
+ }
+ cp++;
+ }
+ bu_vls_strcat(&file_name, file_ext);
+
+ if (binary && output_type == OTYPE_STL) {
+ char buf[81]; /* need exactly 80 chars for header */
+ unsigned char tot_buffer[4];
+
+ if ((fd=open(bu_vls_addr(&file_name),
O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
+ perror(bu_vls_addr(&file_name));
+ bu_log("Cannot open binary output file (%s) for writing\n",
bu_vls_addr(&file_name));
+ bu_vls_free(&file_name);
+ return;
+ }
+
+ /* Write out STL header */
+ memset(buf, 0, sizeof(buf));
+ bu_strlcpy(buf, "BRL-CAD generated STL FILE", sizeof(buf));
+ ret = write(fd, &buf, 80);
+ if (ret < 0) {
+ perror("write");
+ }
+
+ /* write a place keeper for the number of triangles */
+ memset(buf, 0, 4);
+ ret = write(fd, &buf, 4);
+ if (ret < 0) {
+ perror("write");
+ }
+
+ stl_write_bot_binary(bot, fd, dp->d_namep);
+
+ /* Re-position pointer to 80th byte */
+ bu_lseek(fd, 80, SEEK_SET);
+
+ /* Write out number of triangles */
+ *(uint32_t *)tot_buffer = htonl((unsigned long)total_faces);
+ lswap((unsigned int *)tot_buffer);
+ ret = write(fd, tot_buffer, 4);
+ if (ret < 0) {
+ perror("write");
+ }
+
+ close(fd);
+ } else {
+ if ((fp=fopen(bu_vls_addr(&file_name), "wb+")) == NULL) {
+ perror(bu_vls_addr(&file_name));
+ bu_log("Cannot open ASCII output file (%s) for writing\n",
bu_vls_addr(&file_name));
+ bu_vls_free(&file_name);
+ return;
+ }
+
+ switch (output_type) {
+ case OTYPE_DXF:
+ fprintf(fp,
+ "0\nSECTION\n2\nHEADER\n999\n%s (BOT from
%s)\n0\nENDSEC\n0\nSECTION\n2\nENTITIES\n",
+ dp->d_namep, db_g_name);
+ dxf_write_bot(bot, fp, dp->d_namep);
+ fprintf(fp, "0\nENDSEC\n0\nEOF\n");
+ break;
+ case OTYPE_OBJ:
+ v_offset = 1;
+ fprintf(fp, "mtllib %s\n",
bu_vls_addr(&obj_materials_file));
+ if (!pathp) {
+ obj_write_bot(bot, fp, dp->d_namep);
+ } else {
+ char *pathstr = db_path_to_string(pathp);
+ obj_write_bot(bot, fp, pathstr);
+ bu_free(pathstr, "free path");
+ }
+ break;
+ case OTYPE_SAT:
+ curr_line_num = 0;
+
+ sat_write_header(fp);
+
+ sat_write_bot(bot, fp, dp->d_namep);
+ fprintf(fp, "End-of-ACIS-data\n");
+ break;
+ case OTYPE_STL:
+ default:
+ stl_write_bot(bot, fp, dp->d_namep);
+ break;
+ }
+
+ fclose(fp);
+ }
+
+ bu_vls_free(&file_name);
+ } else {
+ if (binary && output_type == OTYPE_STL) {
+ total_faces += bot->num_faces;
+ stl_write_bot_binary(bot, fd, dp->d_namep);
+ } else if (binary && output_type != OTYPE_STL) {
+ bu_log("Unsupported binary file type - only STL is currently
supported\n");
+ return;
+ } else {
+ /* If we get to this point, we need fp - check for it */
+ if (fp) {
+ char *pathstr;
+ switch (output_type) {
+ case OTYPE_DXF:
+ dxf_write_bot(bot, fp, dp->d_namep);
+ break;
+ case OTYPE_OBJ:
+ if (!pathp) {
+ obj_write_bot(bot, fp, dp->d_namep);
+ } else {
+ pathstr = db_path_to_string(pathp);
+ obj_write_bot(bot, fp, pathstr);
+ bu_free(pathstr, "free path");
+ }
+ break;
+ case OTYPE_SAT:
+ sat_write_bot(bot, fp, dp->d_namep);
+ break;
+ case OTYPE_STL:
+ default:
+ stl_write_bot(bot, fp, dp->d_namep);
+ break;
+ }
+ } else {
+ bu_log("_ged_bot_dump: non-binay file requested but fp is NULL!\n");
+ }
+ }
+ }
+}
+
+
+static union tree *
+bot_dump_leaf(struct db_tree_state *UNUSED(tsp),
+ const struct db_full_path *pathp,
+ struct rt_db_internal *UNUSED(ip),
+ void *client_data)
+{
+ int ret;
+ union tree *curtree;
+ mat_t mat;
+ struct directory *dp;
+ struct rt_db_internal intern;
+ struct rt_bot_internal *bot;
+ struct _ged_bot_dump_client_data *gbdcdp = (struct
_ged_bot_dump_client_data *)client_data;
+
+ /* Indicate success by returning something other than TREE_NULL */
+ BU_GET(curtree, union tree);
+ RT_TREE_INIT(curtree);
+ curtree->tr_op = OP_NOP;
+
+ dp = pathp->fp_names[pathp->fp_len-1];
+
+ /* we only dump BOT primitives, so skip some obvious exceptions */
+ if (dp->d_major_type != DB5_MAJORTYPE_BRLCAD || dp->d_flags & RT_DIR_COMB)
+ return curtree;
+
+ MAT_IDN(mat);
+
+ /* get the internal form */
+ ret=rt_db_get_internal(&intern, dp, gbdcdp->gedp->ged_wdbp->dbip, mat,
&rt_uniresource);
+
+ if (ret < 0) {
+ bu_log("ged_bot_leaf: rt_get_internal failure %d on %s\n", ret,
dp->d_namep);
+ return curtree;
+ }
+
+ if (ret != ID_BOT) {
+ bu_log("ged_bot_leaf: %s is not a bot (ignored)\n", dp->d_namep);
+ rt_db_free_internal(&intern);
+ return curtree;
+ }
+
+ bot = (struct rt_bot_internal *)intern.idb_ptr;
+ _ged_bot_dump(dp, pathp, bot, gbdcdp->fp, gbdcdp->fd, gbdcdp->file_ext,
gbdcdp->gedp->ged_wdbp->dbip->dbi_filename);
+ rt_db_free_internal(&intern);
+
+ return curtree;
+}
+
+
+static int
+bot_dump_get_args(struct ged *gedp, int argc, const char *argv[])
+{
+ int c;
+
+ output_type = OTYPE_STL;
+ binary = 0;
+ normals = 0;
+ cfactor = 1.0;
+ output_file = NULL;
+ output_directory = NULL;
+ total_faces = 0;
+ v_offset = 1;
+ curr_line_num = 0;
+ bu_optind = 1;
+
+ /* Get command line options. */
+ while ((c = bu_getopt(argc, (char * const *)argv, "bno:m:t:u:")) != -1) {
+ switch (c) {
+ case 'b': /* Binary output file */
+ binary=1;
+ break;
+ case 'n': /* Binary output file */
+ normals=1;
+ break;
+ case 'm':
+ output_directory = bu_optarg;
+ break;
+ case 'o': /* Output file name. */
+ output_file = bu_optarg;
+ break;
+ case 't':
+ if (BU_STR_EQUAL("dxf", bu_optarg))
+ output_type = OTYPE_DXF;
+ else if (BU_STR_EQUAL("obj", bu_optarg))
+ output_type = OTYPE_OBJ;
+ else if (BU_STR_EQUAL("sat", bu_optarg))
+ output_type = OTYPE_SAT;
+ else if (BU_STR_EQUAL("stl", bu_optarg))
+ output_type = OTYPE_STL;
+ else {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s\n",
argv[0], usage);
+ return GED_ERROR;
+ }
+ break;
+ case 'u':
+ cfactor = bu_units_conversion(bu_optarg);
+ if (ZERO(cfactor))
+ cfactor = 1.0;
+ else
+ cfactor = 1.0 / cfactor;
+
+ break;
+ default:
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s\n", argv[0],
usage);
+ return GED_ERROR;
+ }
+ }
+
+ return GED_OK;
+}
+
+
+int
+ged_bot_dump(struct ged *gedp, int argc, const char *argv[])
+{
+ int ret;
+ struct rt_db_internal intern;
+ struct rt_bot_internal *bot;
+ struct directory *dp;
+ char *file_ext = NULL;
+ FILE *fp = (FILE *)0;
+ int fd = -1;
+ mat_t mat;
+ int i;
+ const char *cmd_name;
+
+ GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+ GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+ /* initialize result */
+ bu_vls_trunc(gedp->ged_result_str, 0);
+
+ /* must be wanting help */
+ if (argc == 1) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s\n", argv[0], usage);
+ return GED_HELP;
+ }
+
+ using_dbot_dump = 0;
+
+ if (bot_dump_get_args(gedp, argc, argv) == GED_ERROR)
+ return GED_ERROR;
+
+ if (bu_optind > argc) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_ERROR;
+ }
+
+ if (output_file && output_directory) {
+ fprintf(stderr, "ERROR: options \"-o\" and \"-m\" are mutually
exclusive\n");
+ return GED_ERROR;
+ }
+
+ if (!output_file && !output_directory) {
+ if (binary) {
+ bu_vls_printf(gedp->ged_result_str, "Can't output binary to
stdout\nUsage: %s %s\n", argv[0], usage);
+ return GED_ERROR;
+ }
+ fp = stdout;
+
+ /* Set this to something non-null in order to possibly write eof */
+ output_file = "stdout";
+ }
+
+ if (output_file) {
+ if (binary && output_type == OTYPE_STL) {
+ char buf[81]; /* need exactly 80 chars for header */
+
+ /* Open binary output file */
+ if ((fd=open(output_file, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
+ perror(argv[0]);
+ bu_vls_printf(gedp->ged_result_str, "Cannot open binary output
file (%s) for writing\n", output_file);
+ return GED_ERROR;
+ }
+
+ /* Write out STL header if output file is binary */
+ memset(buf, 0, sizeof(buf));
+ bu_strlcpy(buf, "BRL-CAD generated STL FILE", sizeof(buf));
+ ret = write(fd, &buf, 80);
+ if (ret < 0) {
+ perror("write");
+ }
+
+ /* write a place keeper for the number of triangles */
+ memset(buf, 0, 4);
+ ret = write(fd, &buf, 4);
+ if (ret < 0) {
+ perror("write");
+ }
+ } else {
+ /* Open ASCII output file */
+ if ((fp=fopen(output_file, "wb+")) == NULL) {
+ perror(argv[0]);
+ bu_vls_printf(gedp->ged_result_str, "Cannot open ascii output
file (%s) for writing\n", output_file);
+ return GED_ERROR;
+ }
+
+ switch (output_type) {
+ case OTYPE_DXF:
+ /* output DXF header and start of TABLES section */
+ fprintf(fp,
+ "0\nSECTION\n2\nHEADER\n999\n%s (All
Bots)\n0\nENDSEC\n0\nSECTION\n2\nENTITIES\n",
+ argv[argc-1]);
+ break;
+ case OTYPE_SAT:
+ sat_write_header(fp);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /* save the command name */
+ cmd_name = argv[0];
+
+ /* skip past the command name and optional args */
+ argc -= bu_optind;
+ argv += bu_optind;
+
+ if (output_directory) {
+ switch (output_type) {
+ case OTYPE_DXF:
+ file_ext = ".dxf";
+ break;
+ case OTYPE_OBJ:
+ file_ext = ".obj";
+ break;
+ case OTYPE_SAT:
+ file_ext = ".sat";
+ break;
+ case OTYPE_STL:
+ default:
+ file_ext = ".stl";
+ break;
+ }
+ }
+
+ MAT_IDN(mat);
+
+ if (argc < 1) {
+ /* dump all the bots */
+ FOR_ALL_DIRECTORY_START(dp, gedp->ged_wdbp->dbip) {
+
+ /* we only dump BOT primitives, so skip some obvious exceptions */
+ if (dp->d_major_type != DB5_MAJORTYPE_BRLCAD) continue;
+ if (dp->d_flags & RT_DIR_COMB) continue;
+
+ /* get the internal form */
+ i = rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, mat,
&rt_uniresource);
+ if (i < 0) {
+ fprintf(stderr, "%s: rt_get_internal failure %d on %s\n",
cmd_name, i, dp->d_namep);
+ continue;
+ }
+
+ if (i != ID_BOT) {
+ continue;
+ }
+
+ bot = (struct rt_bot_internal *)intern.idb_ptr;
+ _ged_bot_dump(dp, NULL, bot, fp, fd, file_ext,
gedp->ged_wdbp->dbip->dbi_filename);
+ rt_db_free_internal(&intern);
+
+ } FOR_ALL_DIRECTORY_END;
+ } else {
+ int ac = 1;
+ int ncpu = 1;
+ char *av[2];
+ struct _ged_bot_dump_client_data gbdcdp = {NULL, NULL, 0, NULL};
+
+ av[1] = (char *)0;
+ gbdcdp.gedp = gedp;
+ gbdcdp.fp = fp;
+ gbdcdp.fd = fd;
+ gbdcdp.file_ext = file_ext;
+
+ for (i = 0; i < argc; ++i) {
+ av[0] = (char *)argv[i];
+ ret = db_walk_tree(gedp->ged_wdbp->dbip,
+ ac,
+ (const char **)av,
+ ncpu,
+ &gedp->ged_wdbp->wdb_initial_tree_state,
+ 0,
+ 0,
+ bot_dump_leaf,
+ (void *)&gbdcdp);
+ }
+ }
+
+
+ if (output_file) {
+ if (binary && output_type == OTYPE_STL) {
+ unsigned char tot_buffer[4];
+
+ /* Re-position pointer to 80th byte */
+ bu_lseek(fd, 80, SEEK_SET);
+
+ /* Write out number of triangles */
+ *(uint32_t *)tot_buffer = htonl((unsigned long)total_faces);
+ lswap((unsigned int *)tot_buffer);
+ ret = write(fd, tot_buffer, 4);
+ if (ret < 0) {
+ perror("write");
+ }
+
+ close(fd);
+ } else {
+ /* end of layers section, start of ENTITIES SECTION */
+ switch (output_type) {
+ case OTYPE_DXF:
+ fprintf(fp, "0\nENDSEC\n0\nEOF\n");
+ break;
+ case OTYPE_SAT:
+ fprintf(fp, "End-of-ACIS-data\n");
+ break;
+ default:
+ break;
+ }
+
+ fclose(fp);
+ }
+ }
+
+ return GED_OK;
+}
+
+
+static void
+write_data_arrows(struct bview_data_arrow_state *gdasp, FILE *fp, int sflag)
+{
+ register int i;
+
+ if (gdasp->gdas_draw) {
+ struct _ged_obj_material *gomp;
+
+ gomp = obj_get_material(gdasp->gdas_color[0],
+ gdasp->gdas_color[1],
+ gdasp->gdas_color[2],
+ 1);
+ fprintf(fp, "usemtl %s\n", bu_vls_addr(&gomp->name));
+
+ if (sflag)
+ fprintf(fp, "g sdata_arrows\n");
+ else
+ fprintf(fp, "g data_arrows\n");
+
+ for (i = 0; i < gdasp->gdas_num_points; i += 2) {
+ point_t A, B;
+ point_t BmA;
+ point_t offset;
+ point_t perp1, perp2;
+ point_t a_base;
+ point_t a_pt1, a_pt2, a_pt3, a_pt4;
+
+ VMOVE(A, gdasp->gdas_points[i]);
+ VMOVE(B, gdasp->gdas_points[i+1]);
+
+ VSUB2(BmA, B, A);
+
+ VUNITIZE(BmA);
+ VSCALE(offset, BmA, -gdasp->gdas_tip_length);
+
+ bn_vec_perp(perp1, BmA);
+ VUNITIZE(perp1);
+
+ VCROSS(perp2, BmA, perp1);
+ VUNITIZE(perp2);
+
+ VSCALE(perp1, perp1, gdasp->gdas_tip_width);
+ VSCALE(perp2, perp2, gdasp->gdas_tip_width);
+
+ VADD2(a_base, B, offset);
+ VADD2(a_pt1, a_base, perp1);
+ VADD2(a_pt2, a_base, perp2);
+ VSUB2(a_pt3, a_base, perp1);
+ VSUB2(a_pt4, a_base, perp2);
+
+ fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(A));
+ fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(B));
+ fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(a_pt1));
+ fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(a_pt2));
+ fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(a_pt3));
+ fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(a_pt4));
+ }
+
+ for (i = 0; i < gdasp->gdas_num_points; i += 2) {
+ fprintf(fp, "l %d %d\n", (i/2*6)+v_offset, (i/2*6)+v_offset+1);
+ fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+1, (i/2*6)+v_offset+2);
+ fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+1, (i/2*6)+v_offset+3);
+ fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+1, (i/2*6)+v_offset+4);
+ fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+1, (i/2*6)+v_offset+5);
+ fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+2, (i/2*6)+v_offset+3);
+ fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+3, (i/2*6)+v_offset+4);
+ fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+4, (i/2*6)+v_offset+5);
+ fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+5, (i/2*6)+v_offset+2);
+ }
+
+ v_offset += ((gdasp->gdas_num_points/2)*6);
+ }
+}
+
+
+static void
+write_data_axes(struct bview_data_axes_state *bndasp, FILE *fp, int sflag)
+{
+ register int i;
+
+ if (bndasp->draw) {
+ fastf_t halfAxesSize;
+ struct _ged_obj_material *gomp;
+
+ halfAxesSize = bndasp->size * 0.5;
+
+ gomp = obj_get_material(bndasp->color[0],
+ bndasp->color[1],
+ bndasp->color[2],
+ 1);
+ fprintf(fp, "usemtl %s\n", bu_vls_addr(&gomp->name));
+
+ if (sflag)
+ fprintf(fp, "g sdata_axes\n");
+ else
+ fprintf(fp, "g data_axes\n");
+
+ for (i = 0; i < bndasp->num_points; ++i) {
+ point_t A, B;
+
+ /* draw X axis with x/y offsets */
+ VSET(A,
+ bndasp->points[i][X] - halfAxesSize,
+ bndasp->points[i][Y],
+ bndasp->points[i][Z]);
+ VSET(B,
+ bndasp->points[i][X] + halfAxesSize,
+ bndasp->points[i][Y],
+ bndasp->points[i][Z]);
+
+ fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(A));
+ fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(B));
+
+ /* draw Y axis with x/y offsets */
+ VSET(A,
+ bndasp->points[i][X],
+ bndasp->points[i][Y] - halfAxesSize,
+ bndasp->points[i][Z]);
+ VSET(B,
+ bndasp->points[i][X],
+ bndasp->points[i][Y] + halfAxesSize,
+ bndasp->points[i][Z]);
+
+ fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(A));
+ fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(B));
+
+ /* draw Z axis with x/y offsets */
+ VSET(A,
+ bndasp->points[i][X],
+ bndasp->points[i][Y],
+ bndasp->points[i][Z] - halfAxesSize);
+ VSET(B,
+ bndasp->points[i][X],
+ bndasp->points[i][Y],
+ bndasp->points[i][Z] + halfAxesSize);
+
+ fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(A));
+ fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(B));
+ }
+
+ for (i = 0; i < bndasp->num_points; ++i) {
+ fprintf(fp, "l %d %d\n", (i*6)+v_offset, (i*6)+v_offset+1);
+ fprintf(fp, "l %d %d\n", (i*6)+v_offset+2, (i*6)+v_offset+3);
+ fprintf(fp, "l %d %d\n", (i*6)+v_offset+4, (i*6)+v_offset+5);
+ }
+
+
+ v_offset += (bndasp->num_points*6);
+ }
+}
+
+
+static void
+write_data_lines(struct bview_data_line_state *gdlsp, FILE *fp, int sflag)
+{
+ register int i;
+
+ if (gdlsp->gdls_draw) {
+ struct _ged_obj_material *gomp;
+
+ gomp = obj_get_material(gdlsp->gdls_color[0],
+ gdlsp->gdls_color[1],
+ gdlsp->gdls_color[2],
+ 1);
+ fprintf(fp, "usemtl %s\n", bu_vls_addr(&gomp->name));
+
+ if (sflag)
+ fprintf(fp, "g sdata_lines\n");
+ else
+ fprintf(fp, "g data_lines\n");
+
+ for (i = 0; i < gdlsp->gdls_num_points; i += 2) {
+ point_t A, B;
+
+ VMOVE(A, gdlsp->gdls_points[i]);
+ VMOVE(B, gdlsp->gdls_points[i+1]);
+
+ fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(A));
+ fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(B));
+ }
+
+ for (i = 0; i < gdlsp->gdls_num_points; i += 2) {
+ fprintf(fp, "l %d %d\n", i+v_offset, i+v_offset+1);
+ }
+
+ v_offset += gdlsp->gdls_num_points;
+ }
+}
+
+
+static void
+obj_write_data(struct ged *gedp, FILE *fp)
+{
+ write_data_arrows(&gedp->ged_gvp->gv_data_arrows, fp, 0);
+ write_data_arrows(&gedp->ged_gvp->gv_sdata_arrows, fp, 1);
+
+ write_data_axes(&gedp->ged_gvp->gv_data_axes, fp, 0);
+ write_data_axes(&gedp->ged_gvp->gv_sdata_axes, fp, 1);
+
+ write_data_lines(&gedp->ged_gvp->gv_data_lines, fp, 0);
+ write_data_lines(&gedp->ged_gvp->gv_sdata_lines, fp, 1);
+}
+
+
+static int
+data_dump(struct ged *gedp, FILE *fp)
+{
+ switch (output_type) {
+ case OTYPE_DXF:
+ break;
+ case OTYPE_OBJ:
+ if (output_directory) {
+ char *cp;
+ struct bu_vls filepath = BU_VLS_INIT_ZERO;
+ FILE *data_fp;
+
+ cp = strrchr(output_directory, '/');
+ if (!cp)
+ cp = (char *)output_directory;
+ else
+ ++cp;
+
+ if (*cp == '\0') {
+ bu_vls_printf(gedp->ged_result_str, "data_dump: bad dirname
- %s\n", output_directory);
+ return GED_ERROR;
+ }
+
+ bu_vls_printf(&filepath, "%s/%s_data.obj", output_directory,
cp);
+
+ if ((data_fp=fopen(bu_vls_addr(&filepath), "wb+")) == NULL) {
+ bu_vls_printf(gedp->ged_result_str, "data_dump: failed to
open %s\n", bu_vls_addr(&filepath));
+ bu_vls_free(&filepath);
+ return GED_ERROR;
+ }
+
+ bu_vls_free(&filepath);
+ obj_write_data(gedp, data_fp);
+ fclose(data_fp);
+ } else
+ if (fp) {
+ obj_write_data(gedp, fp);
+ } else {
+ bu_vls_printf(gedp->ged_result_str, "data_dump: bad FILE
fp\n");
+ return GED_ERROR;
+ }
+
+ break;
+ case OTYPE_SAT:
+ break;
+ case OTYPE_STL:
+ default:
+ break;
+ }
+
+ return GED_OK;
+}
+
+
+int
+ged_dbot_dump(struct ged *gedp, int argc, const char *argv[])
+{
+ int ret;
+ char *file_ext = NULL;
+ FILE *fp = (FILE *)0;
+ int fd = -1;
+ const char *cmd_name;
+
+ GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+ GED_CHECK_DRAWABLE(gedp, GED_ERROR);
+ GED_CHECK_VIEW(gedp, GED_ERROR);
+ GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+ /* initialize result */
+ bu_vls_trunc(gedp->ged_result_str, 0);
+
+ /* must be wanting help */
+ if (argc == 1) {
+ bu_vls_printf(gedp->ged_result_str, usage, argv[0]);
+ return GED_HELP;
+ }
+
+ using_dbot_dump = 1;
+
+ if (bot_dump_get_args(gedp, argc, argv) == GED_ERROR)
+ return GED_ERROR;
+
+ if (bu_optind != argc) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_ERROR;
+ }
+
+ if (output_file && output_directory) {
+ fprintf(stderr, "ERROR: options \"-o\" and \"-m\" are mutually
exclusive\n");
+ return GED_ERROR;
+ }
+
+ if (!output_file && !output_directory) {
+ if (binary) {
+ bu_vls_printf(gedp->ged_result_str, "Can't output binary to
stdout\nUsage: %s %s", argv[0], usage);
+ return GED_ERROR;
+ }
+ fp = stdout;
+
+ /* Set this to something non-null in order to possibly write eof */
+ output_file = "stdout";
+ }
+
+ if (output_file) {
+ if (binary && output_type == OTYPE_STL) {
+ char buf[81]; /* need exactly 80 chars for header */
+
+ /* Open binary output file */
+ if ((fd=open(output_file, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
+ perror(argv[0]);
+ bu_vls_printf(gedp->ged_result_str, "Cannot open binary output
file (%s) for writing\n", output_file);
+ return GED_ERROR;
+ }
+
+ /* Write out STL header if output file is binary */
+ memset(buf, 0, sizeof(buf));
+ bu_strlcpy(buf, "BRL-CAD generated STL FILE", sizeof(buf));
+ ret = write(fd, &buf, 80);
+ if (ret < 0) {
+ perror("write");
+ }
+
+ /* write a place keeper for the number of triangles */
+ memset(buf, 0, 4);
+ ret = write(fd, &buf, 4);
+ if (ret < 0) {
+ perror("write");
+ }
+ } else {
+ /* Open ASCII output file */
+ if ((fp=fopen(output_file, "wb+")) == NULL) {
+ perror(argv[0]);
+ bu_vls_printf(gedp->ged_result_str, "Cannot open ascii output
file (%s) for writing\n", output_file);
+ return GED_ERROR;
+ }
+
+ switch (output_type) {
+ case OTYPE_DXF:
+ /* output DXF header and start of TABLES section */
+ fprintf(fp,
+ "0\nSECTION\n2\nHEADER\n999\n%s (All
Bots)\n0\nENDSEC\n0\nSECTION\n2\nENTITIES\n",
+ argv[argc-1]);
+ break;
+ case OTYPE_SAT:
+ sat_write_header(fp);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /* save the command name */
+ cmd_name = argv[0];
+
+ if (output_directory) {
+ switch (output_type) {
+ case OTYPE_DXF:
+ file_ext = ".dxf";
+ break;
+ case OTYPE_OBJ:
+ file_ext = ".obj";
+
+ BU_LIST_INIT(&HeadObjMaterials);
+
+ {
+ char *cp;
+ struct bu_vls filepath = BU_VLS_INIT_ZERO;
+
+ cp = strrchr(output_directory, '/');
+ if (!cp)
+ cp = (char *)output_directory;
+ else
+ ++cp;
+
+ if (*cp == '\0') {
+ bu_vls_printf(gedp->ged_result_str, "%s: bad dirname -
%s\n", cmd_name, output_directory);
+ return GED_ERROR;
+ }
+
+ bu_vls_trunc(&obj_materials_file, 0);
+ bu_vls_printf(&obj_materials_file, "%s.mtl", cp);
+
+ bu_vls_printf(&filepath, "%s/%s", output_directory,
bu_vls_addr(&obj_materials_file));
+
+ if ((obj_materials_fp=fopen(bu_vls_addr(&filepath), "wb+"))
== NULL) {
+ bu_vls_printf(gedp->ged_result_str, "%s: failed to open
%s\n", cmd_name, bu_vls_addr(&filepath));
+ bu_vls_free(&obj_materials_file);
+ bu_vls_free(&filepath);
+ return GED_ERROR;
+ }
+
+ bu_vls_free(&filepath);
+ }
+
+ num_obj_materials = 0;
+
+ break;
+ case OTYPE_SAT:
+ file_ext = ".sat";
+ break;
+ case OTYPE_STL:
+ default:
+ file_ext = ".stl";
+ break;
+ }
+ } else if (output_type == OTYPE_OBJ) {
+ char *cp;
+
+ bu_vls_trunc(&obj_materials_file, 0);
+
+ cp = strrchr(output_file, '.');
+ if (!cp)
+ bu_vls_printf(&obj_materials_file, "%s.mtl", output_file);
+ else {
+ /* ignore everything after the last '.' */
+ *cp = '\0';
+ bu_vls_printf(&obj_materials_file, "%s.mtl", output_file);
+ *cp = '.';
+ }
+
+ BU_LIST_INIT(&HeadObjMaterials);
+
+ if ((obj_materials_fp=fopen(bu_vls_addr(&obj_materials_file), "wb+"))
== NULL) {
+ bu_vls_printf(gedp->ged_result_str, "%s: failed to open %s\n",
cmd_name, bu_vls_addr(&obj_materials_file));
+ bu_vls_free(&obj_materials_file);
+ fclose(fp);
+ return GED_ERROR;
+ }
+
+ num_obj_materials = 0;
+
+ fprintf(fp, "mtllib %s\n", bu_vls_addr(&obj_materials_file));
+ }
+
+ dl_botdump(gedp->ged_gdp->gd_headDisplay, gedp->ged_wdbp->dbip, fp, fd,
file_ext, output_type, &curr_obj_red, &curr_obj_green, &curr_obj_blue,
&curr_obj_alpha);
+
+ data_dump(gedp, fp);
+
+ if (output_file) {
+ if (binary && output_type == OTYPE_STL) {
+ unsigned char tot_buffer[4];
+
+ /* Re-position pointer to 80th byte */
+ bu_lseek(fd, 80, SEEK_SET);
+
+ /* Write out number of triangles */
+ *(uint32_t *)tot_buffer = htonl((unsigned long)total_faces);
+ lswap((unsigned int *)tot_buffer);
+ ret = write(fd, tot_buffer, 4);
+ if (ret < 0) {
+ perror("write");
+ }
+
+ close(fd);
+ } else {
+ /* end of layers section, start of ENTITIES SECTION */
+ switch (output_type) {
+ case OTYPE_DXF:
+ fprintf(fp, "0\nENDSEC\n0\nEOF\n");
+ break;
+ case OTYPE_SAT:
+ fprintf(fp, "End-of-ACIS-data\n");
+ break;
+ default:
+ break;
+ }
+
+ fclose(fp);
+ }
+ }
+
+ if (output_type == OTYPE_OBJ) {
+ bu_vls_free(&obj_materials_file);
+ obj_free_materials();
+ fclose(obj_materials_fp);
+ }
+
+ return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Copied: brlcad/branches/gedplugins/src/libged/bot/bot_face_fuse.c (from rev
76395, brlcad/branches/gedplugins/src/libged/bot_face_fuse/bot_face_fuse.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/bot/bot_face_fuse.c
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/bot/bot_face_fuse.c 2020-07-21
19:08:41 UTC (rev 76396)
@@ -0,0 +1,90 @@
+/* B O T _ F A C E _ F U S E . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2008-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file libged/bot_face_fuse.c
+ *
+ * The bot_face_fuse command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "rt/geom.h"
+
+#include "../ged_private.h"
+
+
+int
+ged_bot_face_fuse(struct ged *gedp, int argc, const char *argv[])
+{
+ struct directory *old_dp, *new_dp;
+ struct rt_db_internal intern;
+ struct rt_bot_internal *bot;
+ static const char *usage = "new_bot old_bot";
+
+ GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+ GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+ GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+ /* initialize result */
+ bu_vls_trunc(gedp->ged_result_str, 0);
+
+ /* must be wanting help */
+ if (argc == 1) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_HELP;
+ }
+
+ if (argc != 3) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_ERROR;
+ }
+
+ GED_DB_LOOKUP(gedp, old_dp, argv[2], LOOKUP_NOISY, GED_ERROR & GED_QUIET);
+ GED_DB_GET_INTERNAL(gedp, &intern, old_dp, bn_mat_identity,
&rt_uniresource, GED_ERROR);
+
+ if (intern.idb_type != ID_BOT) {
+ bu_vls_printf(gedp->ged_result_str, "%s: %s is not a BOT solid!\n",
argv[0], argv[2]);
+ return GED_ERROR;
+ }
+
+ bot = (struct rt_bot_internal *)intern.idb_ptr;
+ RT_BOT_CK_MAGIC(bot);
+
+ (void) rt_bot_face_fuse(bot);
+
+ GED_DB_DIRADD(gedp, new_dp, argv[1], RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID,
(void *)&intern.idb_type, GED_ERROR);
+ GED_DB_PUT_INTERNAL(gedp, new_dp, &intern, &rt_uniresource, GED_ERROR);
+
+ return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Copied: brlcad/branches/gedplugins/src/libged/bot/bot_face_sort.c (from rev
76395, brlcad/branches/gedplugins/src/libged/bot_face_sort/bot_face_sort.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/bot/bot_face_sort.c
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/bot/bot_face_sort.c 2020-07-21
19:08:41 UTC (rev 76396)
@@ -0,0 +1,116 @@
+/* B O T _ F A C E _ S O R T . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2008-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file libged/bot_face_sort.c
+ *
+ * The bot_face_sort command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "rt/geom.h"
+#include "ged.h"
+
+
+int
+ged_bot_face_sort(struct ged *gedp, int argc, const char *argv[])
+{
+ int i;
+ int tris_per_piece=0;
+ static const char *usage = "triangles_per_piece bot_solid1 [bot_solid2
bot_solid3 ...]";
+
+ GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+ GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+ GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+ /* initialize result */
+ bu_vls_trunc(gedp->ged_result_str, 0);
+
+ /* must be wanting help */
+ if (argc == 1) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_HELP;
+ }
+
+ if (argc < 3) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_ERROR;
+ }
+
+ tris_per_piece = atoi(argv[1]);
+ if (tris_per_piece < 1) {
+ bu_vls_printf(gedp->ged_result_str,
+ "Illegal value for triangle per piece (%s)\n",
+ argv[1]);
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_ERROR;
+ }
+
+ for (i = 2; i < argc; i++) {
+ struct directory *dp;
+ struct rt_db_internal intern;
+ struct rt_bot_internal *bot;
+
+ if ((dp=db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) ==
RT_DIR_NULL) {
+ continue;
+ }
+
+ GED_DB_GET_INTERNAL(gedp, &intern, dp, bn_mat_identity,
gedp->ged_wdbp->wdb_resp, GED_ERROR);
+
+ if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
+ rt_db_free_internal(&intern);
+ bu_vls_printf(gedp->ged_result_str,
+ "%s is not a BOT primitive, skipped\n",
+ dp->d_namep);
+ continue;
+ }
+
+ bot = (struct rt_bot_internal *)intern.idb_ptr;
+ RT_BOT_CK_MAGIC(bot);
+
+ bu_log("processing %s (%zu triangles)\n", dp->d_namep, bot->num_faces);
+
+ if (rt_bot_sort_faces(bot, tris_per_piece)) {
+ rt_db_free_internal(&intern);
+ bu_vls_printf(gedp->ged_result_str,
+ "Face sort failed for %s, this BOT not sorted\n",
+ dp->d_namep);
+ continue;
+ }
+
+ GED_DB_PUT_INTERNAL(gedp, dp, &intern, gedp->ged_wdbp->wdb_resp,
GED_ERROR);
+ }
+
+ return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Copied: brlcad/branches/gedplugins/src/libged/bot/bot_flip.c (from rev 76395,
brlcad/branches/gedplugins/src/libged/bot_flip/bot_flip.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/bot/bot_flip.c
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/bot/bot_flip.c 2020-07-21
19:08:41 UTC (rev 76396)
@@ -0,0 +1,99 @@
+/* B O T _ F L I P . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2008-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file libged/bot_flip.c
+ *
+ * The bot_flip command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "bu/path.h"
+#include "rt/geom.h"
+
+#include "../ged_private.h"
+
+
+int
+ged_bot_flip(struct ged *gedp, int argc, const char *argv[])
+{
+ int i;
+ struct directory *dp;
+ struct rt_db_internal intern;
+ struct rt_bot_internal *bot;
+ static const char *usage = "bot [bot2 bot3 ...]";
+
+ GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+ GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+ GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+ /* initialize result */
+ bu_vls_trunc(gedp->ged_result_str, 0);
+
+ /* must be wanting help */
+ if (argc == 1) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_HELP;
+ }
+
+ for (i = 1; i < argc; ++i) {
+ /* Skip past any path elements */
+ char *obj = (char *)bu_calloc(strlen(argv[i]), sizeof(char),
"ged_bot_flip obj");
+ bu_path_basename(argv[i], obj);
+
+ if (BU_STR_EQUAL(obj, ".")) {
+ /* malformed path, lookup using exactly what was provided */
+ bu_free(obj, "free bu_path_basename");
+ obj = bu_strdup(argv[i]);
+ }
+
+ if ((dp = db_lookup(gedp->ged_wdbp->dbip, obj, LOOKUP_QUIET)) ==
RT_DIR_NULL) {
+ bu_vls_printf(gedp->ged_result_str, "%s: db_lookup(%s) error\n",
argv[0], obj);
+ } else {
+ GED_DB_GET_INTERNAL(gedp, &intern, dp, bn_mat_identity,
&rt_uniresource, GED_ERROR);
+
+ if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
+ bu_vls_printf(gedp->ged_result_str, "%s: %s is not a BOT
solid!\n", argv[0], obj);
+ } else {
+ bot = (struct rt_bot_internal *)intern.idb_ptr;
+ rt_bot_flip(bot);
+
+ GED_DB_PUT_INTERNAL(gedp, dp, &intern,
gedp->ged_wdbp->wdb_resp, GED_ERROR);
+ }
+ }
+ bu_free(obj, "free obj");
+ }
+
+ return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Copied: brlcad/branches/gedplugins/src/libged/bot/bot_fuse.c (from rev 76395,
brlcad/branches/gedplugins/src/libged/bot_fuse/bot_fuse.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/bot/bot_fuse.c
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/bot/bot_fuse.c 2020-07-21
19:08:41 UTC (rev 76396)
@@ -0,0 +1,323 @@
+/* B O T _ F U S E . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2008-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file libged/bot_fuse.c
+ *
+ * The bot_fuse command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "bu/getopt.h"
+#include "bu/parallel.h"
+#include "rt/geom.h"
+#include "bn/plot3.h"
+
+#include "../ged_private.h"
+
+
+static size_t
+show_dangling_edges(struct ged *gedp, const uint32_t *magic_p, const char
*name, int out_type)
+{
+ FILE *plotfp = NULL;
+ const char *manifolds = NULL;
+ const struct edgeuse *eur;
+ int done;
+ point_t pt1, pt2;
+ size_t i, cnt;
+ struct bn_vlblock *vbp = NULL;
+ struct bu_list *vhead = NULL;
+ struct bu_ptbl faces;
+ struct bu_vls plot_file_name = BU_VLS_INIT_ZERO;
+ struct edgeuse *eu = NULL;
+ struct face *fp = NULL;
+ struct faceuse *fu, *fu1, *fu2;
+ struct faceuse *newfu = NULL;
+ struct loopuse *lu = NULL;
+
+ /* out_type: 0 = none, 1 = show, 2 = plot */
+ if (out_type < 0 || out_type > 2) {
+ bu_log("Internal error, open edge test failed.\n");
+ return 0;
+ }
+
+ if (out_type == 1) {
+ vbp = rt_vlblock_init();
+ vhead = bn_vlblock_find(vbp, 0xFF, 0xFF, 0x00);
+ }
+
+ bu_ptbl_init(&faces, 64, "faces buffer");
+ nmg_face_tabulate(&faces, magic_p, &RTG.rtg_vlfree);
+
+ cnt = 0;
+ for (i = 0; i < (size_t)BU_PTBL_LEN(&faces) ; i++) {
+ fp = (struct face *)BU_PTBL_GET(&faces, i);
+ NMG_CK_FACE(fp);
+ fu = fu1 = fp->fu_p;
+ NMG_CK_FACEUSE(fu1);
+ fu2 = fp->fu_p->fumate_p;
+ NMG_CK_FACEUSE(fu2);
+ done = 0;
+ while (!done) {
+ NMG_CK_FACEUSE(fu);
+ for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
+ NMG_CK_LOOPUSE(lu);
+ if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_EDGEUSE_MAGIC) {
+ for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
+ NMG_CK_EDGEUSE(eu);
+ eur = nmg_radial_face_edge_in_shell(eu);
+ newfu = eur->up.lu_p->up.fu_p;
+ while (manifolds &&
+ NMG_MANIFOLDS(manifolds, newfu) &
+ NMG_2MANIFOLD &&
+ eur != eu->eumate_p) {
+ eur = nmg_radial_face_edge_in_shell(eur->eumate_p);
+ newfu = eur->up.lu_p->up.fu_p;
+ }
+ if (eur == eu->eumate_p) {
+ VMOVE(pt1, eu->vu_p->v_p->vg_p->coord);
+ VMOVE(pt2, eu->eumate_p->vu_p->v_p->vg_p->coord);
+ if (out_type == 1) {
+ BN_ADD_VLIST(vbp->free_vlist_hd, vhead, pt1,
BN_VLIST_LINE_MOVE);
+ BN_ADD_VLIST(vbp->free_vlist_hd, vhead, pt2,
BN_VLIST_LINE_DRAW);
+ } else if (out_type == 2) {
+ if (!plotfp) {
+ bu_vls_sprintf(&plot_file_name, "%s.%p.pl",
name, (void *)magic_p);
+ if ((plotfp =
fopen(bu_vls_addr(&plot_file_name), "wb")) == (FILE *)NULL) {
+ bu_vls_free(&plot_file_name);
+ bu_log("Error, unable to create plot
file (%s), open edge test failed.\n",
+ bu_vls_addr(&plot_file_name));
+ return 0;
+ }
+ }
+ pdv_3line(plotfp, pt1, pt2);
+ }
+ cnt++;
+ }
+ }
+ }
+ }
+ if (fu == fu1) fu = fu2;
+ if (fu == fu2) done = 1;
+ };
+
+ }
+
+ if (out_type == 1) {
+ /* Add overlay */
+ _ged_cvt_vlblock_to_solids(gedp, vbp, name, 0);
+ bn_vlblock_free(vbp);
+ bu_log("Showing open edges...\n");
+ } else if (out_type == 2) {
+ if (plotfp) {
+ (void)fclose(plotfp);
+ bu_log("Wrote plot file (%s)\n", bu_vls_addr(&plot_file_name));
+ bu_vls_free(&plot_file_name);
+ }
+ }
+ bu_ptbl_free(&faces);
+
+ return cnt;
+}
+
+
+int
+ged_bot_fuse(struct ged *gedp, int argc, const char **argv)
+{
+ struct directory *old_dp, *new_dp;
+ struct rt_db_internal intern, intern2;
+ struct rt_bot_internal *bot;
+ int count=0;
+ static const char *usage = "new_bot old_bot";
+
+ struct model *m;
+ struct nmgregion *r;
+ int ret, c, i;
+ struct bn_tol *tol = &gedp->ged_wdbp->wdb_tol;
+ int total = 0;
+ volatile int out_type = 0; /* open edge output type: 0 = none, 1 = show, 2
= plot */
+ size_t open_cnt;
+ struct bu_vls name_prefix = BU_VLS_INIT_ZERO;
+
+ /* bu_getopt() options */
+ static const char *bot_fuse_options = "sp";
+ static const char *bot_fuse_options_str = "[-s|-p]";
+
+ GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+ GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+ GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+ /* initialize result */
+ bu_vls_trunc(gedp->ged_result_str, 0);
+
+ /* must be wanting help */
+ if (argc != 3 && argc != 4) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argv[0],
bot_fuse_options_str, usage);
+ return GED_HELP;
+ }
+
+ /* Turn off getopt's error messages */
+ bu_opterr = 0;
+ bu_optind = 1;
+
+ /* get all the option flags from the command line */
+ while ((c=bu_getopt(argc, (char **)argv, bot_fuse_options)) != -1) {
+ switch (c) {
+ case 's':
+ {
+ out_type = 1; /* show open edges */
+ break;
+ }
+ case 'p':
+ {
+ out_type = 2; /* plot open edges */
+ break;
+ }
+ default :
+ {
+ bu_vls_printf(gedp->ged_result_str, "Unknown option: '%c'",
c);
+ return GED_HELP;
+ }
+ }
+ }
+
+ i = argc - 2;
+
+ bu_log("%s: start\n", argv[0]);
+
+ GED_DB_LOOKUP(gedp, old_dp, argv[i+1], LOOKUP_NOISY, GED_ERROR &
GED_QUIET);
+ GED_DB_GET_INTERNAL(gedp, &intern, old_dp, bn_mat_identity,
&rt_uniresource, GED_ERROR);
+
+ if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || intern.idb_minor_type
!= DB5_MINORTYPE_BRLCAD_BOT) {
+ bu_vls_printf(gedp->ged_result_str, "%s: %s is not a BOT solid!\n",
argv[0], argv[i+1]);
+ return GED_ERROR;
+ }
+
+ /* create nmg model structure */
+ m = nmg_mm();
+
+ /* place bot in nmg structure */
+ bu_log("%s: running rt_bot_tess\n", argv[0]);
+ ret = rt_bot_tess(&r, m, &intern, &gedp->ged_wdbp->wdb_ttol, tol);
+
+ /* free internal representation of original bot */
+ rt_db_free_internal(&intern);
+
+ if (ret != 0) {
+ bu_vls_printf(gedp->ged_result_str, "%s: %s fuse failed (1).\n",
argv[0], argv[i+1]);
+ nmg_km(m);
+ return GED_ERROR;
+ }
+
+ total = 0;
+
+ /* Step 1 -- the vertices. */
+ bu_log("%s: running nmg_vertex_fuse\n", argv[0]);
+ count = nmg_vertex_fuse(&m->magic, &RTG.rtg_vlfree, tol);
+ total += count;
+ bu_log("%s: %s, %d vertex fused\n", argv[0], argv[i+1], count);
+
+ /* Step 1.5 -- break edges on vertices, before fusing edges */
+ bu_log("%s: running nmg_break_e_on_v\n", argv[0]);
+ count = nmg_break_e_on_v(&m->magic, &RTG.rtg_vlfree, tol);
+ total += count;
+ bu_log("%s: %s, %d broke 'e' on 'v'\n", argv[0], argv[i+1], count);
+
+ if (total) {
+ struct nmgregion *r2;
+ struct shell *s;
+
+ bu_log("%s: running nmg_make_faces_within_tol\n", argv[0]);
+
+ /* vertices and/or edges have been moved,
+ * may have created out-of-tolerance faces
+ */
+
+ for (BU_LIST_FOR(r2, nmgregion, &m->r_hd)) {
+ for (BU_LIST_FOR(s, shell, &r2->s_hd))
+ nmg_make_faces_within_tol(s, &RTG.rtg_vlfree, tol);
+ }
+ }
+
+ /* Step 2 -- the face geometry */
+ bu_log("%s: running nmg_model_face_fuse\n", argv[0]);
+ count = nmg_model_face_fuse(m, &RTG.rtg_vlfree, tol);
+ total += count;
+ bu_log("%s: %s, %d faces fused\n", argv[0], argv[i+1], count);
+
+ /* Step 3 -- edges */
+ bu_log("%s: running nmg_edge_fuse\n", argv[0]);
+ count = nmg_edge_fuse(&m->magic, &RTG.rtg_vlfree, tol);
+ total += count;
+
+ bu_log("%s: %s, %d edges fused\n", argv[0], argv[i+1], count);
+
+ bu_log("%s: %s, %d total fused\n", argv[0], argv[i+1], total);
+
+ if (!BU_SETJUMP) {
+ /* try */
+
+ /* convert the nmg model back into a bot */
+ bot = nmg_bot(BU_LIST_FIRST(shell, &r->s_hd), &RTG.rtg_vlfree, tol);
+
+ bu_vls_sprintf(&name_prefix, "open_edges.%s", argv[i]);
+ bu_log("%s: running show_dangling_edges\n", argv[0]);
+ open_cnt = show_dangling_edges(gedp, &m->magic,
bu_vls_addr(&name_prefix), out_type);
+ bu_log("%s: WARNING %ld open edges, new BOT may be invalid!!!\n",
argv[0], open_cnt);
+ bu_vls_free(&name_prefix);
+
+ /* free the nmg model structure */
+ nmg_km(m);
+ } else {
+ /* catch */
+ BU_UNSETJUMP;
+ bu_vls_printf(gedp->ged_result_str, "%s: %s fuse failed (2).\n",
argv[0], argv[i+1]);
+ return GED_ERROR;
+ } BU_UNSETJUMP;
+
+ RT_DB_INTERNAL_INIT(&intern2);
+ intern2.idb_major_type = DB5_MAJORTYPE_BRLCAD;
+ intern2.idb_type = ID_BOT;
+ intern2.idb_meth = &OBJ[ID_BOT];
+ intern2.idb_ptr = (void *)bot;
+
+ GED_DB_DIRADD(gedp, new_dp, argv[i], RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID,
(void *)&intern2.idb_type, GED_ERROR);
+ GED_DB_PUT_INTERNAL(gedp, new_dp, &intern2, &rt_uniresource, GED_ERROR);
+
+ bu_log("%s: Created new BOT (%s)\n", argv[0], argv[i]);
+ bu_log("%s: Done.\n", argv[0]);
+
+ return GED_OK;
+}
+
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Copied: brlcad/branches/gedplugins/src/libged/bot/bot_merge.c (from rev 76395,
brlcad/branches/gedplugins/src/libged/bot_merge/bot_merge.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/bot/bot_merge.c
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/bot/bot_merge.c 2020-07-21
19:08:41 UTC (rev 76396)
@@ -0,0 +1,125 @@
+/* B O T _ M E R G E . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2008-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file libged/bot_merge.c
+ *
+ * The bot_merge command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "rt/geom.h"
+
+#include "../ged_private.h"
+
+
+int
+ged_bot_merge(struct ged *gedp, int argc, const char *argv[])
+{
+ struct directory *dp, *new_dp;
+ struct rt_db_internal intern;
+ struct rt_bot_internal **bots;
+ int i, idx;
+ static const char *usage = "bot_dest bot1_src [botn_src]";
+
+ GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+ GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+ GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+ /* initialize result */
+ bu_vls_trunc(gedp->ged_result_str, 0);
+
+ /* must be wanting help */
+ if (argc == 1) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_HELP;
+ }
+
+ bots = (struct rt_bot_internal **)bu_calloc(argc - 1, sizeof(struct
rt_bot_internal *), "bot internal");
+
+ /* read in all the bots */
+ for (idx = 0, i = 2; i < argc; ++i) {
+ if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) ==
RT_DIR_NULL) {
+ continue;
+ }
+
+ GED_DB_GET_INTERNAL(gedp, &intern, dp, bn_mat_identity,
&rt_uniresource, GED_ERROR);
+
+ if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
+ bu_vls_printf(gedp->ged_result_str, "%s: %s is not a BOT solid!
Skipping.\n", argv[0], argv[i]);
+ rt_db_free_internal(&intern);
+ continue;
+ }
+
+ bots[idx] = (struct rt_bot_internal *)intern.idb_ptr;
+
+ intern.idb_ptr = (void *)0;
+ rt_db_free_internal(&intern);
+
+ RT_BOT_CK_MAGIC(bots[idx]);
+ idx++;
+ }
+
+ if (idx == 0) {
+ bu_vls_printf(gedp->ged_result_str, "%s: No BOT solids given.\n",
argv[0]);
+ bu_free(bots, "bots");
+ return GED_ERROR;
+ }
+
+ RT_DB_INTERNAL_INIT(&intern);
+ intern.idb_type = ID_BOT;
+ intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
+ intern.idb_minor_type = DB5_MINORTYPE_BRLCAD_BOT;
+ intern.idb_meth = &OBJ[ID_BOT];
+ intern.idb_ptr = rt_bot_merge(idx, (const struct rt_bot_internal * const
*)(bots));
+
+ GED_DB_DIRADD(gedp, new_dp, argv[1], RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID,
(void *)&intern.idb_type, GED_ERROR);
+ GED_DB_PUT_INTERNAL(gedp, new_dp, &intern, &rt_uniresource, GED_ERROR);
+
+ for (i = 0; i < idx; ++i) {
+ /* fill in an rt_db_internal so we can free it */
+ struct rt_db_internal internal;
+ RT_DB_INTERNAL_INIT(&internal);
+ internal.idb_major_type = DB5_MAJORTYPE_BRLCAD;
+ internal.idb_minor_type = ID_BOT;
+ internal.idb_meth = &OBJ[ID_BOT];
+ internal.idb_ptr = bots[i];
+
+ rt_db_free_internal(&internal);
+ }
+
+ bu_free(bots, "bots");
+
+ return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Copied: brlcad/branches/gedplugins/src/libged/bot/bot_smooth.c (from rev 76395,
brlcad/branches/gedplugins/src/libged/bot_smooth/bot_smooth.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/bot/bot_smooth.c
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/bot/bot_smooth.c 2020-07-21
19:08:41 UTC (rev 76396)
@@ -0,0 +1,137 @@
+/* B O T _ S M O O T H . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2008-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file libged/bot_smooth.c
+ *
+ * The bot_smooth command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "bu/cmd.h"
+#include "rt/geom.h"
+
+#include "../ged_private.h"
+
+
+int
+ged_bot_smooth(struct ged *gedp, int argc, const char *argv[])
+{
+ char *new_bot_name, *old_bot_name;
+ struct directory *dp_old, *dp_new;
+ struct rt_bot_internal *old_bot;
+ struct rt_db_internal intern;
+ fastf_t tolerance_angle=180.0;
+ int arg_index=1;
+ static const char *usage = "[-t angle_tolerance] new_bot old_bot";
+
+ GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+ GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+ GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+ dp_old = dp_new = RT_DIR_NULL;
+
+ /* initialize result */
+ bu_vls_trunc(gedp->ged_result_str, 0);
+
+ /* must be wanting help */
+ if (argc == 1) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_HELP;
+ }
+
+ /* check that we are using a version 5 database */
+ if (db_version(gedp->ged_wdbp->dbip) < 5) {
+ bu_vls_printf(gedp->ged_result_str, "This is an older database
version.\nIt does not support BOT surface normals.\nUse \"dbupgrade\" to
upgrade this database to the current version.\n");
+ return GED_ERROR;
+ }
+
+ if (argc < 3) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_ERROR;
+ }
+
+ while (*argv[arg_index] == '-') {
+ /* this is an option */
+ if (BU_STR_EQUAL(argv[arg_index], "-t")) {
+ arg_index++;
+ tolerance_angle = atof(argv[arg_index]);
+ } else {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_ERROR;
+ }
+ arg_index++;
+ }
+
+ if (arg_index >= argc) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_ERROR;
+ }
+
+ new_bot_name = (char *)argv[arg_index++];
+ old_bot_name = (char *)argv[arg_index];
+
+ GED_DB_LOOKUP(gedp, dp_old, old_bot_name, LOOKUP_QUIET, GED_ERROR);
+
+ if (!BU_STR_EQUAL(old_bot_name, new_bot_name)) {
+ GED_CHECK_EXISTS(gedp, new_bot_name, LOOKUP_QUIET, GED_ERROR);
+ } else {
+ dp_new = dp_old;
+ }
+
+ GED_DB_GET_INTERNAL(gedp, &intern, dp_old, NULL, gedp->ged_wdbp->wdb_resp,
GED_ERROR);
+
+ if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || intern.idb_minor_type
!= DB5_MINORTYPE_BRLCAD_BOT) {
+ bu_vls_printf(gedp->ged_result_str, "%s is not a BOT primitive\n",
old_bot_name);
+ rt_db_free_internal(&intern);
+ return GED_ERROR;
+ }
+
+ old_bot = (struct rt_bot_internal *)intern.idb_ptr;
+ RT_BOT_CK_MAGIC(old_bot);
+
+ if (rt_bot_smooth(old_bot, old_bot_name, gedp->ged_wdbp->dbip,
tolerance_angle*DEG2RAD)) {
+ bu_vls_printf(gedp->ged_result_str, "Failed to smooth %s\n",
old_bot_name);
+ rt_db_free_internal(&intern);
+ return GED_ERROR;
+ }
+
+ if (dp_new == RT_DIR_NULL) {
+ GED_DB_DIRADD(gedp, dp_new, new_bot_name, RT_DIR_PHONY_ADDR, 0,
RT_DIR_SOLID, (void *)&intern.idb_type, GED_ERROR);
+ }
+
+ GED_DB_PUT_INTERNAL(gedp, dp_new, &intern, gedp->ged_wdbp->wdb_resp,
GED_ERROR);
+ rt_db_free_internal(&intern);
+
+ return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Copied: brlcad/branches/gedplugins/src/libged/bot/bot_split.c (from rev 76395,
brlcad/branches/gedplugins/src/libged/bot_split/bot_split.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/bot/bot_split.c
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/bot/bot_split.c 2020-07-21
19:08:41 UTC (rev 76396)
@@ -0,0 +1,168 @@
+/* B O T _ S P L I T . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2008-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file libged/bot_split.c
+ *
+ * The bot_split command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "bu/path.h"
+#include "rt/geom.h" /* for rt_bot_split (in raytrace.h) */
+#include "../ged_private.h"
+
+
+int
+ged_bot_split(struct ged *gedp, int argc, const char *argv[])
+{
+ static const char *usage = "bot [bot2 bot3 ...]";
+
+ int i;
+ struct bu_vls bot_result_list = BU_VLS_INIT_ZERO;
+ struct bu_vls error_str = BU_VLS_INIT_ZERO;
+ struct bu_vls new_bots = BU_VLS_INIT_ZERO;
+ struct directory *dp;
+ struct rt_bot_internal *bot;
+ struct rt_db_internal intern;
+
+ GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+ GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+ GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+ /* initialize result */
+ bu_vls_trunc(gedp->ged_result_str, 0);
+
+ /* must be wanting help */
+ if (argc == 1) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_HELP;
+ }
+
+ for (i = 1; i < argc; ++i) {
+ struct rt_bot_list *headRblp = NULL;
+ /* Skip past any path elements */
+ char *obj = bu_path_basename(argv[i], NULL);
+
+ if (BU_STR_EQUAL(obj, ".")) {
+ /* malformed path, lookup using exactly what was provided */
+ bu_free(obj, "free bu_path_basename");
+ obj = bu_strdup(argv[i]);
+ }
+
+ if ((dp = db_lookup(gedp->ged_wdbp->dbip, obj, LOOKUP_QUIET)) ==
RT_DIR_NULL) {
+ bu_vls_printf(&error_str, "%s: db_lookup(%s) error\n", argv[0],
obj);
+ bu_free(obj, "free obj");
+ continue;
+ }
+
+ GED_DB_GET_INTERNAL(gedp, &intern, dp, bn_mat_identity,
&rt_uniresource, GED_ERROR);
+
+ if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
+ rt_db_free_internal(&intern);
+ bu_vls_printf(&error_str, "%s: %s is not a BOT solid!\n", argv[0],
obj);
+ bu_free(obj, "free obj");
+ continue;
+ }
+
+ bot = (struct rt_bot_internal *)intern.idb_ptr;
+ headRblp = rt_bot_split(bot);
+
+ {
+ int ac = 3;
+ const char *av[4];
+ struct rt_db_internal bot_intern;
+ struct rt_bot_list *rblp;
+
+ av[0] = "make_name";
+ av[1] = "-s";
+ av[2] = "0";
+ av[3] = (char *)0;
+
+ /* Set make_name's count to 0 */
+ ged_make_name(gedp, ac, av);
+
+ ac = 2;
+ av[2] = (char *)0;
+
+ for (BU_LIST_FOR(rblp, rt_bot_list, &headRblp->l)) {
+ /* Get a unique name based on the original name */
+ av[1] = obj;
+ ged_make_name(gedp, ac, av);
+
+ /* Create the bot */
+ RT_DB_INTERNAL_INIT(&bot_intern);
+ bot_intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
+ bot_intern.idb_type = ID_BOT;
+ bot_intern.idb_meth = &OBJ[ID_BOT];
+ bot_intern.idb_ptr = (void *)rblp->bot;
+
+ /* Save new bot name for later use */
+ bu_vls_printf(&new_bots, "%s ",
bu_vls_addr(gedp->ged_result_str));
+
+ dp = db_diradd(gedp->ged_wdbp->dbip,
bu_vls_addr(gedp->ged_result_str), RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void
*)&bot_intern.idb_type);
+ if (dp == RT_DIR_NULL) {
+ bu_vls_printf(&error_str, " failed to be added to the
database.\n");
+ rt_bot_list_free(headRblp, 0);
+ rt_db_free_internal(&intern);
+ } else {
+ if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &bot_intern,
&rt_uniresource) < 0) {
+ bu_vls_printf(&error_str, " failed to be added to the
database.\n");
+ rt_bot_list_free(headRblp, 0);
+ rt_db_free_internal(&intern);
+ }
+ }
+ }
+
+ /* Save the name of the original bot and the new bots as a sublist
*/
+ bu_vls_printf(&bot_result_list, "{%s {%s}} ", obj,
bu_vls_addr(&new_bots));
+
+ bu_vls_trunc(gedp->ged_result_str, 0);
+ bu_vls_trunc(&new_bots, 0);
+ }
+
+ rt_bot_list_free(headRblp, 0);
+ rt_db_free_internal(&intern);
+ bu_free(obj, "free obj");
+ }
+
+ bu_vls_trunc(gedp->ged_result_str, 0);
+ bu_vls_printf(gedp->ged_result_str, "%s {%s}",
bu_vls_addr(&bot_result_list), bu_vls_addr(&error_str));
+
+ bu_vls_free(&bot_result_list);
+ bu_vls_free(&new_bots);
+ bu_vls_free(&error_str);
+
+ return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Copied: brlcad/branches/gedplugins/src/libged/bot/bot_sync.c (from rev 76395,
brlcad/branches/gedplugins/src/libged/bot_sync/bot_sync.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/bot/bot_sync.c
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/bot/bot_sync.c 2020-07-21
19:08:41 UTC (rev 76396)
@@ -0,0 +1,101 @@
+/* B O T _ S Y N C . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2008-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file libged/bot_sync.c
+ *
+ * The bot_sync command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "bu/path.h"
+#include "raytrace.h"
+
+#include "../ged_private.h"
+
+
+int
+ged_bot_sync(struct ged *gedp, int argc, const char *argv[])
+{
+ int i;
+ struct directory *dp;
+ struct rt_db_internal intern;
+ struct rt_bot_internal *bot;
+ static const char *usage = "bot [bot2 bot3 ...]";
+
+ GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+ GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+ GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+ /* initialize result */
+ bu_vls_trunc(gedp->ged_result_str, 0);
+
+ /* must be wanting help */
+ if (argc == 1) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_HELP;
+ }
+
+ for (i = 1; i < argc; ++i) {
+ /* Skip past any path elements */
+ char *obj = bu_path_basename(argv[i], NULL);
+
+ if (BU_STR_EQUAL(obj, ".")) {
+ /* malformed path, lookup using exactly what was provided */
+ bu_free(obj, "free bu_path_basename");
+ obj = bu_strdup(argv[i]);
+ }
+
+ if ((dp = db_lookup(gedp->ged_wdbp->dbip, obj, LOOKUP_QUIET)) ==
RT_DIR_NULL) {
+ bu_vls_printf(gedp->ged_result_str, "%s: db_lookup(%s) error\n",
argv[0], obj);
+ } else {
+
+ GED_DB_GET_INTERNAL(gedp, &intern, dp, bn_mat_identity,
&rt_uniresource, GED_ERROR);
+
+ if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
+ rt_db_free_internal(&intern);
+ bu_vls_printf(gedp->ged_result_str, "%s: %s is not a BOT
solid!\n", argv[0], obj);
+ } else {
+
+ bot = (struct rt_bot_internal *)intern.idb_ptr;
+ rt_bot_sync(bot);
+
+ GED_DB_PUT_INTERNAL(gedp, dp, &intern,
gedp->ged_wdbp->wdb_resp, GED_ERROR);
+ }
+ }
+ bu_free(obj, "free obj");
+ }
+
+ return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Copied: brlcad/branches/gedplugins/src/libged/bot/bot_vertex_fuse.c (from rev
76395, brlcad/branches/gedplugins/src/libged/bot_vertex_fuse/bot_vertex_fuse.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/bot/bot_vertex_fuse.c
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/bot/bot_vertex_fuse.c 2020-07-21
19:08:41 UTC (rev 76396)
@@ -0,0 +1,92 @@
+/* B O T _ V E R T E X _ F U S E . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2008-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file libged/bot_vertex_fuse.c
+ *
+ * The bot_vertex_fuse command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "rt/geom.h"
+
+#include "../ged_private.h"
+
+
+int
+ged_bot_vertex_fuse(struct ged *gedp, int argc, const char *argv[])
+{
+ struct directory *old_dp, *new_dp;
+ struct rt_db_internal intern;
+ struct rt_bot_internal *bot;
+ int count=0;
+ static const char *usage = "new_bot old_bot";
+
+ GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+ GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+ GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+ /* initialize result */
+ bu_vls_trunc(gedp->ged_result_str, 0);
+
+ /* must be wanting help */
+ if (argc == 1) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_HELP;
+ }
+
+ if (argc != 3) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_ERROR;
+ }
+
+ GED_DB_LOOKUP(gedp, old_dp, argv[2], LOOKUP_NOISY, GED_ERROR & GED_QUIET);
+ GED_DB_GET_INTERNAL(gedp, &intern, old_dp, bn_mat_identity,
&rt_uniresource, GED_ERROR);
+
+ if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || intern.idb_minor_type
!= DB5_MINORTYPE_BRLCAD_BOT) {
+ bu_vls_printf(gedp->ged_result_str, "%s: %s is not a BOT solid!\n",
argv[0], argv[2]);
+ return GED_ERROR;
+ }
+
+ bot = (struct rt_bot_internal *)intern.idb_ptr;
+ RT_BOT_CK_MAGIC(bot);
+
+ count = rt_bot_vertex_fuse(bot, &gedp->ged_wdbp->wdb_tol);
+ bu_vls_printf(gedp->ged_result_str, "Fused %d vertices\n", count);
+
+ GED_DB_DIRADD(gedp, new_dp, argv[1], RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID,
(void *)&intern.idb_type, GED_ERROR);
+ GED_DB_PUT_INTERNAL(gedp, new_dp, &intern, &rt_uniresource, GED_ERROR);
+
+ return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
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