Revision: 75280
http://sourceforge.net/p/brlcad/code/75280
Author: starseeker
Date: 2020-04-07 11:22:10 +0000 (Tue, 07 Apr 2020)
Log Message:
-----------
C->C++
Modified Paths:
--------------
brlcad/trunk/src/libged/CMakeLists.txt
brlcad/trunk/src/libged/putmat.c
Added Paths:
-----------
brlcad/trunk/src/libged/concat.cpp
Removed Paths:
-------------
brlcad/trunk/src/libged/concat.c
Modified: brlcad/trunk/src/libged/CMakeLists.txt
===================================================================
--- brlcad/trunk/src/libged/CMakeLists.txt 2020-04-07 01:27:56 UTC (rev
75279)
+++ brlcad/trunk/src/libged/CMakeLists.txt 2020-04-07 11:22:10 UTC (rev
75280)
@@ -107,7 +107,7 @@
comb_color.c
comb_std.c
combmem.c
- concat.c
+ concat.cpp
constraint/constraint.c
copy.c
copyeval.c
Deleted: brlcad/trunk/src/libged/concat.c
===================================================================
--- brlcad/trunk/src/libged/concat.c 2020-04-07 01:27:56 UTC (rev 75279)
+++ brlcad/trunk/src/libged/concat.c 2020-04-07 11:22:10 UTC (rev 75280)
@@ -1,549 +0,0 @@
-/* C O N C A 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/concat.c
- *
- * The concat command.
- *
- */
-
-#include "common.h"
-
-#include <string.h>
-
-#include "bu/cmd.h"
-#include "bu/getopt.h"
-#include "rt/geom.h"
-
-#include "./ged_private.h"
-
-
-/**
- * structure used by the dbconcat command for keeping tract of where
- * objects are being copied to and from, and what type of affix to
- * use.
- */
-struct ged_concat_data {
- int copy_mode;
- struct db_i *old_dbip;
- struct db_i *new_dbip;
- struct bu_vls affix;
-};
-
-
-#define NO_AFFIX 1<<0
-#define AUTO_PREFIX 1<<1
-#define AUTO_SUFFIX 1<<2
-#define CUSTOM_PREFIX 1<<3
-#define CUSTOM_SUFFIX 1<<4
-
-
-/**
- * find a new unique name given a list of previously used names, and
- * the type of naming mode that described what type of affix to use.
- */
-static char *
-get_new_name(const char *name,
- struct db_i *dbip,
- Tcl_HashTable *name_tbl,
- Tcl_HashTable *used_names_tbl,
- struct ged_concat_data *cc_data)
-{
- struct bu_vls new_name = BU_VLS_INIT_ZERO;
- Tcl_HashEntry *ptr = NULL;
- char *aname = NULL;
- char *ret_name = NULL;
- int int_new=0;
- long num=0;
-
- RT_CK_DBI(dbip);
- BU_ASSERT(name_tbl);
- BU_ASSERT(used_names_tbl);
- BU_ASSERT(cc_data);
-
- if (!name) {
- bu_log("WARNING: encountered NULL name, renaming to \"UNKNOWN\"\n");
- name = "UNKNOWN";
- }
-
- ptr = Tcl_CreateHashEntry(name_tbl, name, &int_new);
-
- if (!int_new) {
- return (char *)Tcl_GetHashValue(ptr);
- }
-
- do {
- /* iterate until we find an object name that is not in
- * use, trying to accommodate the user's requested affix
- * naming mode.
- */
-
- bu_vls_trunc(&new_name, 0);
-
- if (cc_data->copy_mode & NO_AFFIX) {
- if (num > 0 && cc_data->copy_mode & CUSTOM_PREFIX) {
- /* auto-increment prefix */
- bu_vls_printf(&new_name, "%ld_", num);
- }
- bu_vls_strcat(&new_name, name);
- if (num > 0 && cc_data->copy_mode & CUSTOM_SUFFIX) {
- /* auto-increment suffix */
- bu_vls_printf(&new_name, "_%ld", num);
- }
- } else if (cc_data->copy_mode & CUSTOM_SUFFIX) {
- /* use custom suffix */
- bu_vls_strcpy(&new_name, name);
- if (num > 0) {
- bu_vls_printf(&new_name, "_%ld_", num);
- }
- bu_vls_vlscat(&new_name, &cc_data->affix);
- } else if (cc_data->copy_mode & CUSTOM_PREFIX) {
- /* use custom prefix */
- bu_vls_vlscat(&new_name, &cc_data->affix);
- if (num > 0) {
- bu_vls_printf(&new_name, "_%ld_", num);
- }
- bu_vls_strcat(&new_name, name);
- } else if (cc_data->copy_mode & AUTO_SUFFIX) {
- /* use auto-incrementing suffix */
- bu_vls_strcat(&new_name, name);
- bu_vls_printf(&new_name, "_%ld", num);
- } else if (cc_data->copy_mode & AUTO_PREFIX) {
- /* use auto-incrementing prefix */
- bu_vls_printf(&new_name, "%ld_", num);
- bu_vls_strcat(&new_name, name);
- } else {
- /* no custom suffix/prefix specified, use prefix */
- if (num > 0) {
- bu_vls_printf(&new_name, "_%ld", num);
- }
- bu_vls_strcpy(&new_name, name);
- }
-
- /* make sure it fits for v4 */
- if (db_version(cc_data->old_dbip) < 5) {
- if (bu_vls_strlen(&new_name) > _GED_V4_MAXNAME) {
- bu_log("ERROR: generated new name [%s] is too long (%zu >
%d)\n", bu_vls_addr(&new_name), bu_vls_strlen(&new_name), _GED_V4_MAXNAME);
- }
- return NULL;
- }
- aname = bu_vls_addr(&new_name);
-
- num++;
-
- } while (db_lookup(dbip, aname, LOOKUP_QUIET) != RT_DIR_NULL ||
- Tcl_FindHashEntry(used_names_tbl, aname) != NULL);
-
- /* if they didn't get what they asked for, warn them */
- if (num > 1) {
- if (cc_data->copy_mode & NO_AFFIX) {
- bu_log("WARNING: unable to import [%s] without an affix, imported
as [%s]\n", name, bu_vls_addr(&new_name));
- } else if (cc_data->copy_mode & CUSTOM_SUFFIX) {
- bu_log("WARNING: unable to import [%s] as [%s%s], imported as
[%s]\n", name, name, bu_vls_addr(&cc_data->affix), bu_vls_addr(&new_name));
- } else if (cc_data->copy_mode & CUSTOM_PREFIX) {
- bu_log("WARNING: unable to import [%s] as [%s%s], imported as
[%s]\n", name, bu_vls_addr(&cc_data->affix), name, bu_vls_addr(&new_name));
- }
- }
-
- /* we should now have a unique name. store it in the hash */
- ret_name = bu_vls_strgrab(&new_name);
- Tcl_SetHashValue(ptr, (ClientData)ret_name);
- (void)Tcl_CreateHashEntry(used_names_tbl, ret_name, &int_new);
- bu_vls_free(&new_name);
-
- return ret_name;
-}
-
-
-static void
-adjust_names(union tree *trp,
- struct db_i *dbip,
- Tcl_HashTable *name_tbl,
- Tcl_HashTable *used_names_tbl,
- struct ged_concat_data *cc_data)
-{
- char *new_name;
-
- if (trp == NULL) {
- return;
- }
-
- switch (trp->tr_op) {
- case OP_DB_LEAF:
- new_name = get_new_name(trp->tr_l.tl_name, dbip,
- name_tbl, used_names_tbl, cc_data);
- if (new_name) {
- bu_free(trp->tr_l.tl_name, "leaf name");
- trp->tr_l.tl_name = bu_strdup(new_name);
- }
- break;
- case OP_UNION:
- case OP_INTERSECT:
- case OP_SUBTRACT:
- case OP_XOR:
- adjust_names(trp->tr_b.tb_left, dbip,
- name_tbl, used_names_tbl, cc_data);
- adjust_names(trp->tr_b.tb_right, dbip,
- name_tbl, used_names_tbl, cc_data);
- break;
- case OP_NOT:
- case OP_GUARD:
- case OP_XNOP:
- adjust_names(trp->tr_b.tb_left, dbip,
- name_tbl, used_names_tbl, cc_data);
- break;
- }
-}
-
-
-static int
-copy_object(struct ged *gedp,
- struct directory *input_dp,
- struct db_i *input_dbip,
- struct db_i *curr_dbip,
- Tcl_HashTable *name_tbl,
- Tcl_HashTable *used_names_tbl,
- struct ged_concat_data *cc_data)
-{
- struct rt_db_internal ip;
- struct rt_extrude_internal *extr;
- struct rt_dsp_internal *dsp;
- struct rt_comb_internal *comb;
- struct directory *new_dp;
- char *new_name;
-
- if (rt_db_get_internal(&ip, input_dp, input_dbip, NULL, &rt_uniresource) <
0) {
- bu_vls_printf(gedp->ged_result_str,
- "Failed to get internal form of object (%s) -
aborting!!!\n",
- input_dp->d_namep);
- return GED_ERROR;
- }
-
- if (ip.idb_major_type == DB5_MAJORTYPE_BRLCAD) {
- /* adjust names of referenced object in any object that reference other
objects */
- switch (ip.idb_minor_type) {
- case DB5_MINORTYPE_BRLCAD_COMBINATION:
- comb = (struct rt_comb_internal *)ip.idb_ptr;
- RT_CK_COMB(comb);
- adjust_names(comb->tree, curr_dbip, name_tbl, used_names_tbl,
cc_data);
- break;
- case DB5_MINORTYPE_BRLCAD_EXTRUDE:
- extr = (struct rt_extrude_internal *)ip.idb_ptr;
- RT_EXTRUDE_CK_MAGIC(extr);
-
- new_name = get_new_name(extr->sketch_name, curr_dbip, name_tbl,
used_names_tbl, cc_data);
- if (new_name) {
- bu_free(extr->sketch_name, "sketch name");
- extr->sketch_name = bu_strdup(new_name);
- }
- break;
- case DB5_MINORTYPE_BRLCAD_DSP:
- dsp = (struct rt_dsp_internal *)ip.idb_ptr;
- RT_DSP_CK_MAGIC(dsp);
-
- if (dsp->dsp_datasrc == RT_DSP_SRC_OBJ) {
- /* This dsp references a database object, may need to
change its name */
- new_name = get_new_name(bu_vls_addr(&dsp->dsp_name),
curr_dbip,
- name_tbl, used_names_tbl,
cc_data);
- if (new_name) {
- bu_vls_free(&dsp->dsp_name);
- bu_vls_strcpy(&dsp->dsp_name, new_name);
- }
- }
- break;
- }
- }
-
- new_name = get_new_name(input_dp->d_namep, curr_dbip, name_tbl,
used_names_tbl, cc_data);
- if (!new_name) {
- new_name = input_dp->d_namep;
- }
- if ((new_dp = db_diradd(curr_dbip, new_name, RT_DIR_PHONY_ADDR, 0,
input_dp->d_flags,
- (void *)&input_dp->d_minor_type)) == RT_DIR_NULL) {
- bu_vls_printf(gedp->ged_result_str,
- "Failed to add new object name (%s) to directory -
aborting!!\n",
- new_name);
- return GED_ERROR;
- }
-
- if (rt_db_put_internal(new_dp, curr_dbip, &ip, &rt_uniresource) < 0) {
- bu_vls_printf(gedp->ged_result_str,
- "Failed to write new object (%s) to database -
aborting!!\n",
- new_name);
- return GED_ERROR;
- }
-
- return GED_OK;
-}
-
-
-int
-ged_concat(struct ged *gedp, int argc, const char *argv[])
-{
- struct db_i *newdbp;
- struct directory *dp;
- Tcl_HashTable name_tbl;
- Tcl_HashTable used_names_tbl;
- Tcl_HashEntry *ptr;
- Tcl_HashSearch search;
- struct bu_attribute_value_set g_avs;
- const char *cp;
- char *colorTab;
- struct ged_concat_data cc_data;
- const char *oldfile;
- static const char *usage = "[-u] [-t] [-c] [-s|-p] file.g [suffix|prefix]";
- int importUnits = 0;
- int importTitle = 0;
- int importColorTable = 0;
- int saveGlobalAttrs = 0;
- int c;
- const char *commandName;
-
- 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);
-
- if (argc < 2) {
- bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
- return GED_ERROR;
- }
-
- bu_vls_init(&cc_data.affix);
- cc_data.copy_mode = 0;
- commandName = argv[0];
-
- /* process args */
- bu_optind = 1;
- bu_opterr = 0;
- while ((c=bu_getopt(argc, (char * const *)argv, "utcsp")) != -1) {
- switch (c) {
- case 'u':
- importUnits = 1;
- break;
- case 't':
- importTitle = 1;
- break;
- case 'c':
- importColorTable = 1;
- break;
- case 'p':
- cc_data.copy_mode |= AUTO_PREFIX;
- break;
- case 's':
- cc_data.copy_mode |= AUTO_SUFFIX;
- break;
- default: {
- bu_vls_printf(gedp->ged_result_str, "Usage: %s %s",
commandName, usage);
- bu_vls_free(&cc_data.affix);
- return GED_ERROR;
- }
- }
- }
- argc -= bu_optind;
- argv += bu_optind;
-
- if (argc == 0) {
- bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage);
- return GED_ERROR;
- }
-
- oldfile = argv[0];
-
- argc--;
- argv++;
-
- if (cc_data.copy_mode) {
- /* specified suffix or prefix explicitly */
-
- if (cc_data.copy_mode & AUTO_PREFIX) {
-
- if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) {
- cc_data.copy_mode = NO_AFFIX | CUSTOM_PREFIX;
- } else {
- (void)bu_vls_strcpy(&cc_data.affix, argv[0]);
- cc_data.copy_mode |= CUSTOM_PREFIX;
- }
-
- } else if (cc_data.copy_mode & AUTO_SUFFIX) {
-
- if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) {
- cc_data.copy_mode = NO_AFFIX | CUSTOM_SUFFIX;
- } else {
- (void)bu_vls_strcpy(&cc_data.affix, argv[0]);
- cc_data.copy_mode |= CUSTOM_SUFFIX;
- }
-
- } else {
- bu_vls_free(&cc_data.affix);
- bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName,
usage);
- return GED_ERROR;
- }
-
- } else {
- /* no prefix/suffix preference, use prefix */
-
- cc_data.copy_mode |= AUTO_PREFIX;
-
- if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) {
- cc_data.copy_mode = NO_AFFIX | CUSTOM_PREFIX;
- } else {
- (void)bu_vls_strcpy(&cc_data.affix, argv[0]);
- cc_data.copy_mode |= CUSTOM_PREFIX;
- }
-
- }
-
- if (db_version(gedp->ged_wdbp->dbip) < 5) {
- if (bu_vls_strlen(&cc_data.affix) > _GED_V4_MAXNAME-1) {
- bu_log("ERROR: affix [%s] is too long for v%d\n",
bu_vls_addr(&cc_data.affix), db_version(gedp->ged_wdbp->dbip));
- bu_vls_free(&cc_data.affix);
- return GED_ERROR;
- }
- }
-
- /* open the input file */
- if ((newdbp = db_open(oldfile, DB_OPEN_READONLY)) == DBI_NULL) {
- bu_vls_free(&cc_data.affix);
- perror(oldfile);
- bu_vls_printf(gedp->ged_result_str, "%s: Can't open geometry database
file %s", commandName, oldfile);
- return GED_ERROR;
- }
-
- if (db_version(newdbp) > 4 && db_version(gedp->ged_wdbp->dbip) < 5) {
- bu_vls_free(&cc_data.affix);
- bu_vls_printf(gedp->ged_result_str, "%s: databases are incompatible,
use dbupgrade on %s first",
- commandName, gedp->ged_wdbp->dbip->dbi_filename);
- return GED_ERROR;
- }
-
- db_dirbuild(newdbp);
-
- cc_data.new_dbip = newdbp;
- cc_data.old_dbip = gedp->ged_wdbp->dbip;
-
- /* visit each directory pointer in the input database */
- Tcl_InitHashTable(&name_tbl, TCL_STRING_KEYS);
- Tcl_InitHashTable(&used_names_tbl, TCL_STRING_KEYS);
-
- if (importUnits || importTitle || importColorTable) {
- saveGlobalAttrs = 1;
- }
- FOR_ALL_DIRECTORY_START(dp, newdbp) {
- if (dp->d_major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY) {
- if (saveGlobalAttrs) {
- if (db5_get_attributes(newdbp, &g_avs, dp)) {
- bu_vls_printf(gedp->ged_result_str, "%s: Can't get global
attributes from %s", commandName, oldfile);
- return GED_ERROR;
- }
- }
- continue;
- }
- copy_object(gedp, dp, newdbp, gedp->ged_wdbp->dbip, &name_tbl,
&used_names_tbl, &cc_data);
- } FOR_ALL_DIRECTORY_END;
-
- bu_vls_free(&cc_data.affix);
- rt_mempurge(&(newdbp->dbi_freep));
-
- /* Free all the directory entries, and close the input database */
- db_close(newdbp);
-
- if (importColorTable) {
- if ((cp = bu_avs_get(&g_avs, "regionid_colortable")) != NULL) {
- colorTab = bu_strdup(cp);
- db5_import_color_table(colorTab);
- bu_free(colorTab, "colorTab");
- } else {
- bu_vls_printf(gedp->ged_result_str, "%s: no region color table "
- "was found in %s to import\n", commandName, oldfile);
- }
- } else if (saveGlobalAttrs) {
- bu_avs_remove(&g_avs, "regionid_colortable");
- }
-
- if (importTitle) {
- if ((cp = bu_avs_get(&g_avs, "title")) != NULL) {
- char *oldTitle = gedp->ged_wdbp->dbip->dbi_title;
- gedp->ged_wdbp->dbip->dbi_title = bu_strdup(cp);
- if (oldTitle) {
- bu_free(oldTitle, "old title");
- }
- } else {
- bu_vls_printf(gedp->ged_result_str,
- "%s: no title was found in %s to import\n", commandName,
- oldfile);
- }
- } else if (saveGlobalAttrs) {
- bu_avs_remove(&g_avs, "title");
- }
-
- if (importUnits) {
- if ((cp = bu_avs_get(&g_avs, "units")) != NULL) {
- double dd;
- if (sscanf(cp, "%lf", &dd) != 1 || NEAR_ZERO(dd, VUNITIZE_TOL)) {
- bu_log("copy_object(%s): improper database, %s object attribute
'units'=%s is invalid\n",
- oldfile, DB5_GLOBAL_OBJECT_NAME, cp);
- bu_avs_remove(&g_avs, "units");
- } else {
- gedp->ged_wdbp->dbip->dbi_local2base = dd;
- gedp->ged_wdbp->dbip->dbi_base2local = 1 / dd;
- }
- } else {
- bu_vls_printf(gedp->ged_result_str,
- "%s: no units were found in %s to import\n", commandName,
- oldfile);
- }
- } else if (saveGlobalAttrs) {
- bu_avs_remove(&g_avs, "units");
- }
-
- if (saveGlobalAttrs) {
- dp = db_lookup(gedp->ged_wdbp->dbip, DB5_GLOBAL_OBJECT_NAME,
LOOKUP_NOISY);
- db5_update_attributes(dp, &g_avs, gedp->ged_wdbp->dbip);
- }
-
- db_sync(gedp->ged_wdbp->dbip); /* force changes to disk */
-
- /* Update references. */
- db_update_nref(gedp->ged_wdbp->dbip, &rt_uniresource);
-
- /* Free the Hash tables */
- ptr = Tcl_FirstHashEntry(&name_tbl, &search);
- while (ptr) {
- bu_free((char *)Tcl_GetHashValue(ptr), "new name");
- ptr = Tcl_NextHashEntry(&search);
- }
- Tcl_DeleteHashTable(&name_tbl);
- Tcl_DeleteHashTable(&used_names_tbl);
-
- return GED_OK;
-}
-
-
-/*
- * Local Variables:
- * tab-width: 8
- * mode: C
- * indent-tabs-mode: t
- * c-file-style: "stroustrup"
- * End:
- * ex: shiftwidth=4 tabstop=8
- */
Copied: brlcad/trunk/src/libged/concat.cpp (from rev 75279,
brlcad/trunk/src/libged/concat.c)
===================================================================
--- brlcad/trunk/src/libged/concat.cpp (rev 0)
+++ brlcad/trunk/src/libged/concat.cpp 2020-04-07 11:22:10 UTC (rev 75280)
@@ -0,0 +1,549 @@
+/* C O N C A 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/concat.c
+ *
+ * The concat command.
+ *
+ */
+
+#include "common.h"
+
+#include <string.h>
+
+#include "bu/cmd.h"
+#include "bu/getopt.h"
+#include "rt/geom.h"
+
+#include "./ged_private.h"
+
+
+/**
+ * structure used by the dbconcat command for keeping tract of where
+ * objects are being copied to and from, and what type of affix to
+ * use.
+ */
+struct ged_concat_data {
+ int copy_mode;
+ struct db_i *old_dbip;
+ struct db_i *new_dbip;
+ struct bu_vls affix;
+};
+
+
+#define NO_AFFIX 1<<0
+#define AUTO_PREFIX 1<<1
+#define AUTO_SUFFIX 1<<2
+#define CUSTOM_PREFIX 1<<3
+#define CUSTOM_SUFFIX 1<<4
+
+
+/**
+ * find a new unique name given a list of previously used names, and
+ * the type of naming mode that described what type of affix to use.
+ */
+static char *
+get_new_name(const char *name,
+ struct db_i *dbip,
+ Tcl_HashTable *name_tbl,
+ Tcl_HashTable *used_names_tbl,
+ struct ged_concat_data *cc_data)
+{
+ struct bu_vls new_name = BU_VLS_INIT_ZERO;
+ Tcl_HashEntry *ptr = NULL;
+ char *aname = NULL;
+ char *ret_name = NULL;
+ int int_new=0;
+ long num=0;
+
+ RT_CK_DBI(dbip);
+ BU_ASSERT(name_tbl);
+ BU_ASSERT(used_names_tbl);
+ BU_ASSERT(cc_data);
+
+ if (!name) {
+ bu_log("WARNING: encountered NULL name, renaming to \"UNKNOWN\"\n");
+ name = "UNKNOWN";
+ }
+
+ ptr = Tcl_CreateHashEntry(name_tbl, name, &int_new);
+
+ if (!int_new) {
+ return (char *)Tcl_GetHashValue(ptr);
+ }
+
+ do {
+ /* iterate until we find an object name that is not in
+ * use, trying to accommodate the user's requested affix
+ * naming mode.
+ */
+
+ bu_vls_trunc(&new_name, 0);
+
+ if (cc_data->copy_mode & NO_AFFIX) {
+ if (num > 0 && cc_data->copy_mode & CUSTOM_PREFIX) {
+ /* auto-increment prefix */
+ bu_vls_printf(&new_name, "%ld_", num);
+ }
+ bu_vls_strcat(&new_name, name);
+ if (num > 0 && cc_data->copy_mode & CUSTOM_SUFFIX) {
+ /* auto-increment suffix */
+ bu_vls_printf(&new_name, "_%ld", num);
+ }
+ } else if (cc_data->copy_mode & CUSTOM_SUFFIX) {
+ /* use custom suffix */
+ bu_vls_strcpy(&new_name, name);
+ if (num > 0) {
+ bu_vls_printf(&new_name, "_%ld_", num);
+ }
+ bu_vls_vlscat(&new_name, &cc_data->affix);
+ } else if (cc_data->copy_mode & CUSTOM_PREFIX) {
+ /* use custom prefix */
+ bu_vls_vlscat(&new_name, &cc_data->affix);
+ if (num > 0) {
+ bu_vls_printf(&new_name, "_%ld_", num);
+ }
+ bu_vls_strcat(&new_name, name);
+ } else if (cc_data->copy_mode & AUTO_SUFFIX) {
+ /* use auto-incrementing suffix */
+ bu_vls_strcat(&new_name, name);
+ bu_vls_printf(&new_name, "_%ld", num);
+ } else if (cc_data->copy_mode & AUTO_PREFIX) {
+ /* use auto-incrementing prefix */
+ bu_vls_printf(&new_name, "%ld_", num);
+ bu_vls_strcat(&new_name, name);
+ } else {
+ /* no custom suffix/prefix specified, use prefix */
+ if (num > 0) {
+ bu_vls_printf(&new_name, "_%ld", num);
+ }
+ bu_vls_strcpy(&new_name, name);
+ }
+
+ /* make sure it fits for v4 */
+ if (db_version(cc_data->old_dbip) < 5) {
+ if (bu_vls_strlen(&new_name) > _GED_V4_MAXNAME) {
+ bu_log("ERROR: generated new name [%s] is too long (%zu >
%d)\n", bu_vls_addr(&new_name), bu_vls_strlen(&new_name), _GED_V4_MAXNAME);
+ }
+ return NULL;
+ }
+ aname = bu_vls_addr(&new_name);
+
+ num++;
+
+ } while (db_lookup(dbip, aname, LOOKUP_QUIET) != RT_DIR_NULL ||
+ Tcl_FindHashEntry(used_names_tbl, aname) != NULL);
+
+ /* if they didn't get what they asked for, warn them */
+ if (num > 1) {
+ if (cc_data->copy_mode & NO_AFFIX) {
+ bu_log("WARNING: unable to import [%s] without an affix, imported
as [%s]\n", name, bu_vls_addr(&new_name));
+ } else if (cc_data->copy_mode & CUSTOM_SUFFIX) {
+ bu_log("WARNING: unable to import [%s] as [%s%s], imported as
[%s]\n", name, name, bu_vls_addr(&cc_data->affix), bu_vls_addr(&new_name));
+ } else if (cc_data->copy_mode & CUSTOM_PREFIX) {
+ bu_log("WARNING: unable to import [%s] as [%s%s], imported as
[%s]\n", name, bu_vls_addr(&cc_data->affix), name, bu_vls_addr(&new_name));
+ }
+ }
+
+ /* we should now have a unique name. store it in the hash */
+ ret_name = bu_vls_strgrab(&new_name);
+ Tcl_SetHashValue(ptr, (ClientData)ret_name);
+ (void)Tcl_CreateHashEntry(used_names_tbl, ret_name, &int_new);
+ bu_vls_free(&new_name);
+
+ return ret_name;
+}
+
+
+static void
+adjust_names(union tree *trp,
+ struct db_i *dbip,
+ Tcl_HashTable *name_tbl,
+ Tcl_HashTable *used_names_tbl,
+ struct ged_concat_data *cc_data)
+{
+ char *new_name;
+
+ if (trp == NULL) {
+ return;
+ }
+
+ switch (trp->tr_op) {
+ case OP_DB_LEAF:
+ new_name = get_new_name(trp->tr_l.tl_name, dbip,
+ name_tbl, used_names_tbl, cc_data);
+ if (new_name) {
+ bu_free(trp->tr_l.tl_name, "leaf name");
+ trp->tr_l.tl_name = bu_strdup(new_name);
+ }
+ break;
+ case OP_UNION:
+ case OP_INTERSECT:
+ case OP_SUBTRACT:
+ case OP_XOR:
+ adjust_names(trp->tr_b.tb_left, dbip,
+ name_tbl, used_names_tbl, cc_data);
+ adjust_names(trp->tr_b.tb_right, dbip,
+ name_tbl, used_names_tbl, cc_data);
+ break;
+ case OP_NOT:
+ case OP_GUARD:
+ case OP_XNOP:
+ adjust_names(trp->tr_b.tb_left, dbip,
+ name_tbl, used_names_tbl, cc_data);
+ break;
+ }
+}
+
+
+static int
+copy_object(struct ged *gedp,
+ struct directory *input_dp,
+ struct db_i *input_dbip,
+ struct db_i *curr_dbip,
+ Tcl_HashTable *name_tbl,
+ Tcl_HashTable *used_names_tbl,
+ struct ged_concat_data *cc_data)
+{
+ struct rt_db_internal ip;
+ struct rt_extrude_internal *extr;
+ struct rt_dsp_internal *dsp;
+ struct rt_comb_internal *comb;
+ struct directory *new_dp;
+ char *new_name;
+
+ if (rt_db_get_internal(&ip, input_dp, input_dbip, NULL, &rt_uniresource) <
0) {
+ bu_vls_printf(gedp->ged_result_str,
+ "Failed to get internal form of object (%s) -
aborting!!!\n",
+ input_dp->d_namep);
+ return GED_ERROR;
+ }
+
+ if (ip.idb_major_type == DB5_MAJORTYPE_BRLCAD) {
+ /* adjust names of referenced object in any object that reference other
objects */
+ switch (ip.idb_minor_type) {
+ case DB5_MINORTYPE_BRLCAD_COMBINATION:
+ comb = (struct rt_comb_internal *)ip.idb_ptr;
+ RT_CK_COMB(comb);
+ adjust_names(comb->tree, curr_dbip, name_tbl, used_names_tbl,
cc_data);
+ break;
+ case DB5_MINORTYPE_BRLCAD_EXTRUDE:
+ extr = (struct rt_extrude_internal *)ip.idb_ptr;
+ RT_EXTRUDE_CK_MAGIC(extr);
+
+ new_name = get_new_name(extr->sketch_name, curr_dbip, name_tbl,
used_names_tbl, cc_data);
+ if (new_name) {
+ bu_free(extr->sketch_name, "sketch name");
+ extr->sketch_name = bu_strdup(new_name);
+ }
+ break;
+ case DB5_MINORTYPE_BRLCAD_DSP:
+ dsp = (struct rt_dsp_internal *)ip.idb_ptr;
+ RT_DSP_CK_MAGIC(dsp);
+
+ if (dsp->dsp_datasrc == RT_DSP_SRC_OBJ) {
+ /* This dsp references a database object, may need to
change its name */
+ new_name = get_new_name(bu_vls_addr(&dsp->dsp_name),
curr_dbip,
+ name_tbl, used_names_tbl,
cc_data);
+ if (new_name) {
+ bu_vls_free(&dsp->dsp_name);
+ bu_vls_strcpy(&dsp->dsp_name, new_name);
+ }
+ }
+ break;
+ }
+ }
+
+ new_name = get_new_name(input_dp->d_namep, curr_dbip, name_tbl,
used_names_tbl, cc_data);
+ if (!new_name) {
+ new_name = input_dp->d_namep;
+ }
+ if ((new_dp = db_diradd(curr_dbip, new_name, RT_DIR_PHONY_ADDR, 0,
input_dp->d_flags,
+ (void *)&input_dp->d_minor_type)) == RT_DIR_NULL) {
+ bu_vls_printf(gedp->ged_result_str,
+ "Failed to add new object name (%s) to directory -
aborting!!\n",
+ new_name);
+ return GED_ERROR;
+ }
+
+ if (rt_db_put_internal(new_dp, curr_dbip, &ip, &rt_uniresource) < 0) {
+ bu_vls_printf(gedp->ged_result_str,
+ "Failed to write new object (%s) to database -
aborting!!\n",
+ new_name);
+ return GED_ERROR;
+ }
+
+ return GED_OK;
+}
+
+
+int
+ged_concat(struct ged *gedp, int argc, const char *argv[])
+{
+ struct db_i *newdbp;
+ struct directory *dp;
+ Tcl_HashTable name_tbl;
+ Tcl_HashTable used_names_tbl;
+ Tcl_HashEntry *ptr;
+ Tcl_HashSearch search;
+ struct bu_attribute_value_set g_avs;
+ const char *cp;
+ char *colorTab;
+ struct ged_concat_data cc_data;
+ const char *oldfile;
+ static const char *usage = "[-u] [-t] [-c] [-s|-p] file.g [suffix|prefix]";
+ int importUnits = 0;
+ int importTitle = 0;
+ int importColorTable = 0;
+ int saveGlobalAttrs = 0;
+ int c;
+ const char *commandName;
+
+ 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);
+
+ if (argc < 2) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+ return GED_ERROR;
+ }
+
+ bu_vls_init(&cc_data.affix);
+ cc_data.copy_mode = 0;
+ commandName = argv[0];
+
+ /* process args */
+ bu_optind = 1;
+ bu_opterr = 0;
+ while ((c=bu_getopt(argc, (char * const *)argv, "utcsp")) != -1) {
+ switch (c) {
+ case 'u':
+ importUnits = 1;
+ break;
+ case 't':
+ importTitle = 1;
+ break;
+ case 'c':
+ importColorTable = 1;
+ break;
+ case 'p':
+ cc_data.copy_mode |= AUTO_PREFIX;
+ break;
+ case 's':
+ cc_data.copy_mode |= AUTO_SUFFIX;
+ break;
+ default: {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s",
commandName, usage);
+ bu_vls_free(&cc_data.affix);
+ return GED_ERROR;
+ }
+ }
+ }
+ argc -= bu_optind;
+ argv += bu_optind;
+
+ if (argc == 0) {
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage);
+ return GED_ERROR;
+ }
+
+ oldfile = argv[0];
+
+ argc--;
+ argv++;
+
+ if (cc_data.copy_mode) {
+ /* specified suffix or prefix explicitly */
+
+ if (cc_data.copy_mode & AUTO_PREFIX) {
+
+ if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) {
+ cc_data.copy_mode = NO_AFFIX | CUSTOM_PREFIX;
+ } else {
+ (void)bu_vls_strcpy(&cc_data.affix, argv[0]);
+ cc_data.copy_mode |= CUSTOM_PREFIX;
+ }
+
+ } else if (cc_data.copy_mode & AUTO_SUFFIX) {
+
+ if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) {
+ cc_data.copy_mode = NO_AFFIX | CUSTOM_SUFFIX;
+ } else {
+ (void)bu_vls_strcpy(&cc_data.affix, argv[0]);
+ cc_data.copy_mode |= CUSTOM_SUFFIX;
+ }
+
+ } else {
+ bu_vls_free(&cc_data.affix);
+ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName,
usage);
+ return GED_ERROR;
+ }
+
+ } else {
+ /* no prefix/suffix preference, use prefix */
+
+ cc_data.copy_mode |= AUTO_PREFIX;
+
+ if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) {
+ cc_data.copy_mode = NO_AFFIX | CUSTOM_PREFIX;
+ } else {
+ (void)bu_vls_strcpy(&cc_data.affix, argv[0]);
+ cc_data.copy_mode |= CUSTOM_PREFIX;
+ }
+
+ }
+
+ if (db_version(gedp->ged_wdbp->dbip) < 5) {
+ if (bu_vls_strlen(&cc_data.affix) > _GED_V4_MAXNAME-1) {
+ bu_log("ERROR: affix [%s] is too long for v%d\n",
bu_vls_addr(&cc_data.affix), db_version(gedp->ged_wdbp->dbip));
+ bu_vls_free(&cc_data.affix);
+ return GED_ERROR;
+ }
+ }
+
+ /* open the input file */
+ if ((newdbp = db_open(oldfile, DB_OPEN_READONLY)) == DBI_NULL) {
+ bu_vls_free(&cc_data.affix);
+ perror(oldfile);
+ bu_vls_printf(gedp->ged_result_str, "%s: Can't open geometry database
file %s", commandName, oldfile);
+ return GED_ERROR;
+ }
+
+ if (db_version(newdbp) > 4 && db_version(gedp->ged_wdbp->dbip) < 5) {
+ bu_vls_free(&cc_data.affix);
+ bu_vls_printf(gedp->ged_result_str, "%s: databases are incompatible,
use dbupgrade on %s first",
+ commandName, gedp->ged_wdbp->dbip->dbi_filename);
+ return GED_ERROR;
+ }
+
+ db_dirbuild(newdbp);
+
+ cc_data.new_dbip = newdbp;
+ cc_data.old_dbip = gedp->ged_wdbp->dbip;
+
+ /* visit each directory pointer in the input database */
+ Tcl_InitHashTable(&name_tbl, TCL_STRING_KEYS);
+ Tcl_InitHashTable(&used_names_tbl, TCL_STRING_KEYS);
+
+ if (importUnits || importTitle || importColorTable) {
+ saveGlobalAttrs = 1;
+ }
+ FOR_ALL_DIRECTORY_START(dp, newdbp) {
+ if (dp->d_major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY) {
+ if (saveGlobalAttrs) {
+ if (db5_get_attributes(newdbp, &g_avs, dp)) {
+ bu_vls_printf(gedp->ged_result_str, "%s: Can't get global
attributes from %s", commandName, oldfile);
+ return GED_ERROR;
+ }
+ }
+ continue;
+ }
+ copy_object(gedp, dp, newdbp, gedp->ged_wdbp->dbip, &name_tbl,
&used_names_tbl, &cc_data);
+ } FOR_ALL_DIRECTORY_END;
+
+ bu_vls_free(&cc_data.affix);
+ rt_mempurge(&(newdbp->dbi_freep));
+
+ /* Free all the directory entries, and close the input database */
+ db_close(newdbp);
+
+ if (importColorTable) {
+ if ((cp = bu_avs_get(&g_avs, "regionid_colortable")) != NULL) {
+ colorTab = bu_strdup(cp);
+ db5_import_color_table(colorTab);
+ bu_free(colorTab, "colorTab");
+ } else {
+ bu_vls_printf(gedp->ged_result_str, "%s: no region color table "
+ "was found in %s to import\n", commandName, oldfile);
+ }
+ } else if (saveGlobalAttrs) {
+ bu_avs_remove(&g_avs, "regionid_colortable");
+ }
+
+ if (importTitle) {
+ if ((cp = bu_avs_get(&g_avs, "title")) != NULL) {
+ char *oldTitle = gedp->ged_wdbp->dbip->dbi_title;
+ gedp->ged_wdbp->dbip->dbi_title = bu_strdup(cp);
+ if (oldTitle) {
+ bu_free(oldTitle, "old title");
+ }
+ } else {
+ bu_vls_printf(gedp->ged_result_str,
+ "%s: no title was found in %s to import\n", commandName,
+ oldfile);
+ }
+ } else if (saveGlobalAttrs) {
+ bu_avs_remove(&g_avs, "title");
+ }
+
+ if (importUnits) {
+ if ((cp = bu_avs_get(&g_avs, "units")) != NULL) {
+ double dd;
+ if (sscanf(cp, "%lf", &dd) != 1 || NEAR_ZERO(dd, VUNITIZE_TOL)) {
+ bu_log("copy_object(%s): improper database, %s object attribute
'units'=%s is invalid\n",
+ oldfile, DB5_GLOBAL_OBJECT_NAME, cp);
+ bu_avs_remove(&g_avs, "units");
+ } else {
+ gedp->ged_wdbp->dbip->dbi_local2base = dd;
+ gedp->ged_wdbp->dbip->dbi_base2local = 1 / dd;
+ }
+ } else {
+ bu_vls_printf(gedp->ged_result_str,
+ "%s: no units were found in %s to import\n", commandName,
+ oldfile);
+ }
+ } else if (saveGlobalAttrs) {
+ bu_avs_remove(&g_avs, "units");
+ }
+
+ if (saveGlobalAttrs) {
+ dp = db_lookup(gedp->ged_wdbp->dbip, DB5_GLOBAL_OBJECT_NAME,
LOOKUP_NOISY);
+ db5_update_attributes(dp, &g_avs, gedp->ged_wdbp->dbip);
+ }
+
+ db_sync(gedp->ged_wdbp->dbip); /* force changes to disk */
+
+ /* Update references. */
+ db_update_nref(gedp->ged_wdbp->dbip, &rt_uniresource);
+
+ /* Free the Hash tables */
+ ptr = Tcl_FirstHashEntry(&name_tbl, &search);
+ while (ptr) {
+ bu_free((char *)Tcl_GetHashValue(ptr), "new name");
+ ptr = Tcl_NextHashEntry(&search);
+ }
+ Tcl_DeleteHashTable(&name_tbl);
+ Tcl_DeleteHashTable(&used_names_tbl);
+
+ return GED_OK;
+}
+
+
+/*
+ * Local Variables:
+ * tab-width: 8
+ * mode: C
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Modified: brlcad/trunk/src/libged/putmat.c
===================================================================
--- brlcad/trunk/src/libged/putmat.c 2020-04-07 01:27:56 UTC (rev 75279)
+++ brlcad/trunk/src/libged/putmat.c 2020-04-07 11:22:10 UTC (rev 75280)
@@ -218,7 +218,7 @@
bu_vls_printf(avp, "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 ");
break;
}
- /* Sometimes the matrix is sent through Tcl as one long string.
+ /* Sometimes the matrix is sent through as one long string.
* Copy it so we can crack it, below.
*/
avp = bu_vls_vlsinit();
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