Revision: 76851
http://sourceforge.net/p/brlcad/code/76851
Author: starseeker
Date: 2020-08-19 17:50:31 +0000 (Wed, 19 Aug 2020)
Log Message:
-----------
Break out primitive specific logic into files, and wire up the summary function
of the analyze command as a subcommand.
Modified Paths:
--------------
brlcad/branches/analyze_cmd/src/libged/analyze/CMakeLists.txt
brlcad/branches/analyze_cmd/src/libged/analyze/analyze.cpp
brlcad/branches/analyze_cmd/src/libged/analyze/ged_analyze.h
brlcad/branches/analyze_cmd/src/libged/analyze/util.cpp
Added Paths:
-----------
brlcad/branches/analyze_cmd/src/libged/analyze/arb8.cpp
brlcad/branches/analyze_cmd/src/libged/analyze/arbn.cpp
brlcad/branches/analyze_cmd/src/libged/analyze/ars.cpp
brlcad/branches/analyze_cmd/src/libged/analyze/sketch.cpp
brlcad/branches/analyze_cmd/src/libged/analyze/superell.cpp
Removed Paths:
-------------
brlcad/branches/analyze_cmd/src/libged/analyze/analyze.c
Modified: brlcad/branches/analyze_cmd/src/libged/analyze/CMakeLists.txt
===================================================================
--- brlcad/branches/analyze_cmd/src/libged/analyze/CMakeLists.txt
2020-08-19 15:26:00 UTC (rev 76850)
+++ brlcad/branches/analyze_cmd/src/libged/analyze/CMakeLists.txt
2020-08-19 17:50:31 UTC (rev 76851)
@@ -8,6 +8,11 @@
set(analyze_srcs
analyze.cpp
+ arb8.cpp
+ arbn.cpp
+ ars.cpp
+ superell.cpp
+ sketch.cpp
util.cpp
)
@@ -22,7 +27,6 @@
CMakeLists.txt
${analyze_srcs}
ged_analyze.h
- analyze.c
)
# Local Variables:
Deleted: brlcad/branches/analyze_cmd/src/libged/analyze/analyze.c
===================================================================
--- brlcad/branches/analyze_cmd/src/libged/analyze/analyze.c 2020-08-19
15:26:00 UTC (rev 76850)
+++ brlcad/branches/analyze_cmd/src/libged/analyze/analyze.c 2020-08-19
17:50:31 UTC (rev 76851)
@@ -1,1341 +0,0 @@
-/* A N A L Y Z E . C
- * BRL-CAD
- *
- * Copyright (c) 1985-2020 United States Government as represented by
- * the U.S. Army Research Laboratory.
- *
- * This program 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 program 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/analyze.c
- *
- * The analyze command.
- *
- */
-
-#include "common.h"
-
-#include <math.h>
-#include <string.h>
-#include <assert.h>
-
-#include "vmath.h"
-#include "bn.h"
-#include "bg/polygon.h"
-#include "rt/arb_edit.h"
-#include "raytrace.h"
-#include "rt/geom.h"
-
-#include "../ged_private.h"
-
-/**
- * TODO: primitives that still need implementing
- * ehy
- * metaball
- * nmg
- */
-
-/* Conversion factor for Gallons to cubic millimeters */
-#define GALLONS_TO_MM3 3785411.784
-
-
-/* ARB face printout array */
-static const int prface[5][6] = {
- {123, 124, 234, 134, -111, -111}, /* ARB4 */
- {1234, 125, 235, 345, 145, -111}, /* ARB5 */
- {1234, 2365, 1564, 512, 634, -111}, /* ARB6 */
- {1234, 567, 145, 2376, 1265, 4375}, /* ARB7 */
- {1234, 5678, 1584, 2376, 1265, 4378}, /* ARB8 */
-};
-
-
-/* edge definition array */
-static const int nedge[5][24] = {
- {0, 1, 1, 2, 2, 0, 0, 3, 3, 2, 1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1}, /* ARB4 */
- {0, 1, 1, 2, 2, 3, 0, 3, 0, 4, 1, 4, 2, 4, 3, 4, -1, -1, -1, -1, -1, -1,
-1, -1}, /* ARB5 */
- {0, 1, 1, 2, 2, 3, 0, 3, 0, 4, 1, 4, 2, 5, 3, 5, 4, 5, -1, -1, -1, -1, -1,
-1}, /* ARB6 */
- {0, 1, 1, 2, 2, 3, 0, 3, 0, 4, 3, 4, 1, 5, 2, 6, 4, 5, 5, 6, 4, 6, -1,
-1}, /* ARB7 */
- {0, 1, 1, 2, 2, 3, 0, 3, 0, 4, 4, 5, 1, 5, 5, 6, 6, 7, 4, 7, 3, 7, 2, 6},
/* ARB8 */
-};
-
-
-/* contains information used to analyze a polygonal face */
-struct poly_face
-{
- char label[5];
- size_t npts;
- point_t *pts;
- plane_t plane_eqn;
- fastf_t area;
-};
-
-
-#define POLY_FACE_INIT_ZERO { { 0, 0, 0, 0, 0 }, 0, NULL, HINIT_ZERO, 0.0 }
-
-#define ADD_PT(face, pt) do { VMOVE((face).pts[(face).npts], (pt));
(face).npts++; } while (0)
-
-/* structures and subroutines for analyze pretty printing */
-
-#define FBUFSIZ 100
-#define NFIELDS 9
-#define NOT_A_PLANE -1
-typedef struct row_field
-{
- int nchars;
- char buf[FBUFSIZ];
-} field_t;
-
-typedef struct table_row
-{
- int nfields;
- field_t fields[NFIELDS];
-} row_t;
-
-typedef struct table
-{
- int nrows;
- row_t *rows;
-} table_t;
-
-void get_dashes(field_t *f, const int ndashes)
-{
- int i;
- f->buf[0] = '\0';
- for (i = 0; i < ndashes; ++i) {
- bu_strlcat(f->buf, "-", FBUFSIZ);
- }
- f->nchars = ndashes;
-}
-
-
-void print_volume_table(struct ged *gedp
- , const fastf_t tot_vol
- , const fastf_t tot_area
- , const fastf_t tot_gallons
- )
-{
-
-/* table format
-
- +------------------------------------+
- | Volume = 7999999999.99999905 |
- | Surface Area = 24000000.00000000 |
- | Gallons = 2113.37641887 |
- +------------------------------------+
-
-*/
- /* track actual table column widths */
- /* this table has 1 column (plus a name column) */
- int maxwidth[2] = {0, 0};
- field_t dashes;
- char* fnames[3] = {"Volume",
- "Surface Area",
- "Gallons"};
- int indent = 4; /* number spaces to indent the table */
- int table_width_chars;
- table_t table;
- int i, nd, field;
-
- table.nrows = 3;
- table.rows = (row_t *)bu_calloc(3, sizeof(row_t), "print_volume_table:
rows");
- for (i = 0; i < table.nrows; ++i) {
- fastf_t val = 0.0;
-
- /* field 0 */
- field = 0;
- table.rows[i].fields[0].nchars =
snprintf(table.rows[i].fields[field].buf, FBUFSIZ, "%s",
- fnames[i]);
- if (maxwidth[field] < table.rows[i].fields[field].nchars)
- maxwidth[field] = table.rows[i].fields[field].nchars;
-
- if (i == 0) {
- val = tot_vol;
- } else if (i == 1) {
- val = tot_area;
- } else if (i == 2) {
- val = tot_gallons;
- }
-
- /* field 1 */
- field = 1;
- if (val < 0) {
- table.rows[i].fields[1].nchars =
snprintf(table.rows[i].fields[field].buf, FBUFSIZ, "COULD NOT DETERMINE");
- } else {
- table.rows[i].fields[1].nchars =
snprintf(table.rows[i].fields[field].buf, FBUFSIZ, "%10.8f", val);
- }
- if (maxwidth[field] < table.rows[i].fields[field].nchars)
- maxwidth[field] = table.rows[i].fields[field].nchars;
- }
-
- /* get total table width */
- table_width_chars = maxwidth[0] + maxwidth[1];
- table_width_chars += 2 + 2; /* 2 chars at each end of a row */
- table_width_chars += 3; /* ' = ' between the two fields of a row */
-
- /* newline following previous table */
- bu_vls_printf(gedp->ged_result_str, "\n");
-
- /* header row 1 */
- nd = table_width_chars - 4;
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%-*.*s+-%-*.*s-+\n",
- indent, indent, " ",
- nd, nd, dashes.buf);
-
- /* the three data rows */
- for (i = 0; i < table.nrows; ++i) {
- bu_vls_printf(gedp->ged_result_str, "%-*.*s| %-*.*s = %*.*s |\n",
- indent, indent, " ",
- maxwidth[0], maxwidth[0], table.rows[i].fields[0].buf,
- maxwidth[1], maxwidth[1], table.rows[i].fields[1].buf);
- }
-
- /* closing table row */
- bu_vls_printf(gedp->ged_result_str, "%-*.*s+-%-*.*s-+\n",
- indent, indent, " ",
- nd, nd, dashes.buf);
- bu_free((char *)table.rows, "print_volume_table: rows");
-}
-
-
-void print_edges_table(struct ged *gedp, table_t *table)
-{
-
-/* table header
-
-
+--------------------+--------------------+--------------------+--------------------+
- | EDGE LEN | EDGE LEN | EDGE LEN | EDGE
LEN |
-
+--------------------+--------------------+--------------------+--------------------+
-
-*/
-
- int i;
- int tcol, nd, nrow, nrows;
- int maxwidth[] = {0, 0, 0,
- 0, 0, 0,
- 0, 0};
- int indent = 2;
- field_t dashes;
- char EDGE[] = {"EDGE"};
- int elen = strlen(EDGE);
- char LEN[] = {"LENGTH"};
- int llen = strlen(LEN);
- char buf[FBUFSIZ];
-
- /* put four edges per row making 8 columns */
- /* this table has 8 columns per row: 2 columns per edge; 4 edges per row */
-
- /* collect max table column widths */
- tcol = 0;
- for (i = 0; i < table->nrows; ++i) {
- /* field 0 */
- int field = 0;
- if (maxwidth[tcol] < table->rows[i].fields[field].nchars)
- maxwidth[tcol] = table->rows[i].fields[field].nchars;
- if (maxwidth[tcol] < elen)
- maxwidth[tcol] = elen;
-
- /* field 1 */
- field = 1;
- if (maxwidth[tcol+1] < table->rows[i].fields[field].nchars)
- maxwidth[tcol+1] = table->rows[i].fields[field].nchars;
- if (maxwidth[tcol] < llen)
- maxwidth[tcol] = llen;
-
- /* iterate on columns */
- tcol += 2;
- tcol = tcol > 6 ? 0 : tcol;
- }
-
- /* header row 1 */
- /* print dashes in 4 sets */
- nd = maxwidth[0] + maxwidth[1] + 3; /* 1 space between numbers and one at
each end */
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%-*.*s+%-*.*s",
- indent, indent, " ",
- nd, nd, dashes.buf);
- nd = maxwidth[2] + maxwidth[3] + 3; /* 1 space between numbers and one at
each end */
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "+%-*.*s",
- nd, nd, dashes.buf);
- nd = maxwidth[4] + maxwidth[5] + 3; /* 1 space between numbers and one at
each end */
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "+%-*.*s",
- nd, nd, dashes.buf);
- nd = maxwidth[6] + maxwidth[7] + 3; /* 1 space between numbers and one at
each end */
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "+%-*.*s+\n",
- nd, nd, dashes.buf);
-
- /* header row 2 */
- /* print titles in 4 sets */
-
- /* bu_vls_printf can't handle this at the moment */
- bu_vls_printf(gedp->ged_result_str, "%-*.*s| %-*.*s %*.*s ",
- indent, indent, " ",
- maxwidth[0], maxwidth[0], EDGE,
- maxwidth[1], maxwidth[1], LEN);
- bu_vls_printf(gedp->ged_result_str, "| %-*.*s %*.*s ",
- maxwidth[2], maxwidth[2], EDGE,
- maxwidth[3], maxwidth[3], LEN);
- bu_vls_printf(gedp->ged_result_str, "| %-*.*s %*.*s ",
- maxwidth[4], maxwidth[4], EDGE,
- maxwidth[5], maxwidth[5], LEN);
- bu_vls_printf(gedp->ged_result_str, "| %-*.*s %*.*s |\n",
- maxwidth[6], maxwidth[6], EDGE,
- maxwidth[7], maxwidth[7], LEN);
-
- /* header row 3 */
- /* print dashes in 4 sets */
- nd = maxwidth[0] + maxwidth[1] + 3; /* 1 space between numbers and one at
each end */
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%-*.*s+%-*.*s",
- indent, indent, " ",
- nd, nd, dashes.buf);
- nd = maxwidth[2] + maxwidth[3] + 3; /* 1 space between numbers and one at
each end */
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "+%-*.*s",
- nd, nd, dashes.buf);
- nd = maxwidth[4] + maxwidth[5] + 3; /* 1 space between numbers and one at
each end */
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "+%-*.*s",
- nd, nd, dashes.buf);
- nd = maxwidth[6] + maxwidth[7] + 3; /* 1 space between numbers and one at
each end */
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "+%-*.*s+\n",
- nd, nd, dashes.buf);
-
- /* print the data lines */
- /* collect max table column widths */
- tcol = 0;
- nrow = 0;
- for (i = 0; i < table->nrows; ++i) {
- int field;
-
- if (tcol == 0) {
- /* need to start a row */
- snprintf(buf, FBUFSIZ, "%-*.*s|",
- indent, indent, " ");
- bu_vls_printf(gedp->ged_result_str, "%s", buf);
- }
-
- /* data in sets of two */
- /* field 0 */
- field = 0;
- /* FIXME: using snprintf because bu_vls_printf is broken for complex
formats */
- snprintf(buf, FBUFSIZ, " %-*.*s",
- maxwidth[tcol], maxwidth[tcol],
table->rows[i].fields[field].buf);
- bu_vls_printf(gedp->ged_result_str, "%s", buf);
-
- /* field 1 */
- field = 1;
- /* FIXME: using snprintf because bu_vls_printf is broken for complex
formats */
- snprintf(buf, FBUFSIZ, " %-*.*s |",
- maxwidth[tcol+1], maxwidth[tcol+1],
table->rows[i].fields[field].buf);
- bu_vls_printf(gedp->ged_result_str, "%s", buf);
-
- /* iterate on columns */
- tcol += 2;
-
- if (tcol > 6) {
- /* time for a newline to end the row */
- bu_vls_printf(gedp->ged_result_str, "\n");
- tcol = 0;
- ++nrow;
- }
- }
-
- /* we may have a row to finish */
- nrows = table->nrows % 4;
- if (nrows) {
- assert(tcol < 8);
-
- /* write blanks */
- while (tcol < 7) {
-
- /* data in sets of two */
- /* this is field 0 */
- /* FIXME: using snprintf because bu_vls_printf is broken for
complex formats */
- snprintf(buf, FBUFSIZ, " %-*.*s",
- maxwidth[tcol], maxwidth[tcol], " ");
- bu_vls_printf(gedp->ged_result_str, "%s", buf);
-
- /* this is field 1 */
- /* FIXME: using snprintf because bu_vls_printf is broken for
complex formats */
- snprintf(buf, FBUFSIZ, " %-*.*s |",
- maxwidth[tcol+1], maxwidth[tcol+1], " ");
- bu_vls_printf(gedp->ged_result_str, "%s", buf);
-
- /* iterate on columns */
- tcol += 2;
-
- if (tcol > 6) {
- /* time for a newline to end the row */
- bu_vls_printf(gedp->ged_result_str, "\n");
- }
- }
- }
-
- /* close the table */
- /* print dashes in 4 sets */
- nd = maxwidth[0] + maxwidth[1] + 3; /* 1 space between numbers and one at
each end */
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%-*.*s+%-*.*s",
- indent, indent, " ",
- nd, nd, dashes.buf);
- nd = maxwidth[2] + maxwidth[3] + 3; /* 1 space between numbers and one at
each end */
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "+%-*.*s",
- nd, nd, dashes.buf);
- nd = maxwidth[4] + maxwidth[5] + 3; /* 1 space between numbers and one at
each end */
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "+%-*.*s",
- nd, nd, dashes.buf);
- nd = maxwidth[6] + maxwidth[7] + 3; /* 1 space between numbers and one at
each end */
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "+%-*.*s+\n",
- nd, nd, dashes.buf);
-}
-
-
-void print_faces_table(struct ged *gedp, table_t *table)
-{
-
-/* table header
-
-
+------+-----------------------------+--------------------------------------------------+-----------------+
- | FACE | ROT FB | PLANE EQUATION
| SURFACE AREA |
-
+------+-----------------------------+--------------------------------------------------+-----------------+
-
-*/
-
- /* track actual table column widths */
- /* this table has 8 columns */
- int maxwidth[8] = {0, 0, 0,
- 0, 0, 0,
- 0, 0};
- int i, j;
- int c0, h1a, h1b, h1c;
- int h2a, h2b, h2c;
- int c2, c2a, c2b, c2c;
- int f7, f7a, f7b, f7c;
- int nd, tnd;
- field_t dashes;
- char ROT[] = {"ROT"};
- char FB[] = {"FB"};
- char PA[] = {"PLANE EQUATION"};
- char SA[] = {"SURFACE AREA"};
-
- /* get max fields widths */
- for (i = 0; i < table->nrows; ++i) {
- for (j = 0; j < table->rows[i].nfields; ++j) {
- if (table->rows[i].fields[j].nchars > maxwidth[j])
- maxwidth[j] = table->rows[i].fields[j].nchars;
- }
- }
-
- /* blank line following previous table */
- bu_vls_printf(gedp->ged_result_str, "\n");
-
- /* get max width of header columns (not counting single space on either
side) */
- c0 = maxwidth[0] > 4 ? maxwidth[0] : 4;
-
- /* print "ROT" in center of field 1 space */
- h1b = strlen(ROT);
- h1a = (maxwidth[1] - h1b)/2;
- h1c = (maxwidth[1] - h1b - h1a);
-
- /* print "FB" in center of field 2 space */
- h2b = strlen(FB);
- h2a = (maxwidth[2] - h2b)/2;
- h2c = (maxwidth[2] - h2b - h2a);
-
- /* get width of subcolumns of header column 2 */
- /* print "PLANE EQUATION" in center of columns 2 space */
- c2 = maxwidth[3] + maxwidth[4] + maxwidth[5] + maxwidth[6] + 3; /* 3
spaces between fields */
- c2b = strlen(PA);
- c2a = (c2 - c2b)/2;
- c2c = (c2 - c2b - c2a);
-
- /* print "SURFACE AREA" in center of field 7 space */
- f7b = strlen(SA);
- f7 = maxwidth[7] > f7b ? maxwidth[7] : f7b;
- f7a = (f7 - f7b)/2;
- f7c = (f7 - f7b - f7a);
-
- /* print the pieces */
-
- /* header row 1 */
- bu_vls_printf(gedp->ged_result_str, "+-");
- nd = c0; tnd = nd;
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%-*.*s",
- nd, nd, dashes.buf);
- bu_vls_printf(gedp->ged_result_str, "-+-");
- nd = h1a + h1b + h1c + 1 + h2a + h2b + h2c; tnd += nd + 3;
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%*.*s",
- nd, nd, dashes.buf);
- bu_vls_printf(gedp->ged_result_str, "-+-");
- nd = c2a + c2b + c2c; tnd += nd + 3;
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%*.*s",
- nd, nd, dashes.buf);
- bu_vls_printf(gedp->ged_result_str, "-+-");
- nd = f7a + f7b + f7c; tnd += nd + 3;
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%*.*s",
- nd, nd, dashes.buf);
- bu_vls_printf(gedp->ged_result_str, "-+\n");
-
- /* header row 2 */
- bu_vls_printf(gedp->ged_result_str, "| ");
-
- bu_vls_printf(gedp->ged_result_str, "%-*.*s", c0, c0, "FACE");
-
- bu_vls_printf(gedp->ged_result_str, " | ");
-
-
- bu_vls_printf(gedp->ged_result_str, "%*.*s", h1a, h1a, " ");
-
- bu_vls_printf(gedp->ged_result_str, "%*.*s", h1b, h1b, ROT);
-
- bu_vls_printf(gedp->ged_result_str, "%*.*s", h1c+h2a, h1c+h2a, " ");
-
- bu_vls_printf(gedp->ged_result_str, "%*.*s", h2b, h2b, FB);
-
- bu_vls_printf(gedp->ged_result_str, "%*.*s ", h2c, h2c, " ");
-
-
- bu_vls_printf(gedp->ged_result_str, " | ");
-
-
- bu_vls_printf(gedp->ged_result_str, "%*.*s", c2a, c2a, " ");
-
- bu_vls_printf(gedp->ged_result_str, "%*.*s", c2b, c2b, PA);
-
- bu_vls_printf(gedp->ged_result_str, "%*.*s", c2c, c2c, " ");
-
-
- bu_vls_printf(gedp->ged_result_str, " | ");
-
- bu_vls_printf(gedp->ged_result_str, "%*.*s", f7a, f7a, " ");
-
- bu_vls_printf(gedp->ged_result_str, "%*.*s", f7b, f7b, SA);
-
- bu_vls_printf(gedp->ged_result_str, "%*.*s", f7c, f7c, " ");
-
- bu_vls_printf(gedp->ged_result_str, " |\n");
-
- /* header row 3 */
- bu_vls_printf(gedp->ged_result_str, "+-");
- nd = c0; tnd = nd;
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%-*.*s",
- nd, nd, dashes.buf);
- bu_vls_printf(gedp->ged_result_str, "-+-");
- nd = h1a + h1b + h1c + 1 + h2a + h2b + h2c; tnd += nd + 3;
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%*.*s",
- nd, nd, dashes.buf);
- bu_vls_printf(gedp->ged_result_str, "-+-");
- nd = c2a + c2b + c2c; tnd += nd + 3;
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%*.*s",
- nd, nd, dashes.buf);
- bu_vls_printf(gedp->ged_result_str, "-+-");
- nd = f7a + f7b + f7c; tnd += nd + 3;
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%*.*s",
- nd, nd, dashes.buf);
- bu_vls_printf(gedp->ged_result_str, "-+\n");
-
- /* output table data rows */
- for (i = 0; i < table->nrows; ++i) {
- /* may not have a row with data */
- if (table->rows[i].nfields == 0)
- continue;
- if (table->rows[i].nfields == NOT_A_PLANE)
- bu_vls_printf(gedp->ged_result_str, "***NOT A PLANE ***");
-
- bu_vls_printf(gedp->ged_result_str, "|");
- for (j = 0; j < table->rows[i].nfields; ++j) {
- assert(table->rows[i].fields[j].buf);
- bu_vls_printf(gedp->ged_result_str, " %*.*s",
- maxwidth[j], maxwidth[j],
- table->rows[i].fields[j].buf);
- /* do we need a separator? */
- if (j == 0 || j == 2 || j == 6 || j == 7)
- bu_vls_printf(gedp->ged_result_str, " |");
- }
- /* close the row */
- bu_vls_printf(gedp->ged_result_str, "\n");
- }
-
- /* close the table with the ender row */
- bu_vls_printf(gedp->ged_result_str, "+-");
- nd = c0; tnd = nd;
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%-*.*s",
- nd, nd, dashes.buf);
- bu_vls_printf(gedp->ged_result_str, "-+-");
- nd = h1a + h1b + h1c + 1 + h2a + h2b + h2c; tnd += nd + 3;
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%*.*s",
- nd, nd, dashes.buf);
- bu_vls_printf(gedp->ged_result_str, "-+-");
- nd = c2a + c2b + c2c; tnd += nd + 3;
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%*.*s",
- nd, nd, dashes.buf);
- bu_vls_printf(gedp->ged_result_str, "-+-");
- nd = f7a + f7b + f7c; tnd += nd + 3;
- get_dashes(&dashes, nd);
- bu_vls_printf(gedp->ged_result_str, "%*.*s",
- nd, nd, dashes.buf);
- bu_vls_printf(gedp->ged_result_str, "-+\n");
-}
-
-
-/**
- * general analyze function for primitives that can be analyzed using volume
- * and surface area functions from the rt_functab.
- * Currently used for:
- * - ell
- * - tor
- * - tgc
- * - rpc
- * - eto
- * - epa
- * - part
- * - rhc
- */
-HIDDEN void
-analyze_general(struct ged *gedp, const struct rt_db_internal *ip)
-{
- fastf_t vol, area;
- point_t centroid;
-
- vol = area = -1.0;
-
- if (OBJ[ip->idb_minor_type].ft_volume) {
- OBJ[ip->idb_minor_type].ft_volume(&vol, ip);
- }
- if (OBJ[ip->idb_minor_type].ft_surf_area) {
- OBJ[ip->idb_minor_type].ft_surf_area(&area, ip);
- }
-
- if (OBJ[ip->idb_minor_type].ft_centroid) {
- OBJ[ip->idb_minor_type].ft_centroid(¢roid, ip);
- bu_vls_printf(gedp->ged_result_str, "\n Centroid: (%g, %g, %g)\n",
- centroid[X] * gedp->ged_wdbp->dbip->dbi_base2local,
- centroid[Y] * gedp->ged_wdbp->dbip->dbi_base2local,
- centroid[Z] * gedp->ged_wdbp->dbip->dbi_base2local);
- }
-
- print_volume_table(gedp,
- vol
- * gedp->ged_wdbp->dbip->dbi_base2local
- * gedp->ged_wdbp->dbip->dbi_base2local
- * gedp->ged_wdbp->dbip->dbi_base2local,
- area
- * gedp->ged_wdbp->dbip->dbi_base2local
- * gedp->ged_wdbp->dbip->dbi_base2local,
- vol/GALLONS_TO_MM3
- );
-}
-
-
-/**
- * finds direction cosines and rotation, fallback angles of a unit vector
- * angles = pointer to 5 fastf_t's to store angles
- * unitv = pointer to the unit vector (previously computed)
- */
-HIDDEN void
-findang(fastf_t *angles, fastf_t *unitv)
-{
- int i;
- fastf_t f;
-
- /* convert direction cosines into axis angles */
- for (i = X; i <= Z; i++) {
- if (unitv[i] <= -1.0)
- angles[i] = -90.0;
- else if (unitv[i] >= 1.0)
- angles[i] = 90.0;
- else
- angles[i] = acos(unitv[i]) * RAD2DEG;
- }
-
- /* fallback angle */
- if (unitv[Z] <= -1.0)
- unitv[Z] = -1.0;
- else if (unitv[Z] >= 1.0)
- unitv[Z] = 1.0;
- angles[4] = asin(unitv[Z]);
-
- /* rotation angle */
- /* For the tolerance below, on an SGI 4D/70, cos(asin(1.0)) != 0.0
- * with an epsilon of +/- 1.0e-17, so the tolerance below was
- * substituted for the original +/- 1.0e-20.
- */
- if ((f = cos(angles[4])) > 1.0e-16 || f < -1.0e-16) {
- f = unitv[X]/f;
- if (f <= -1.0)
- angles[3] = 180.0;
- else if (f >= 1.0)
- angles[3] = 0.0;
- else
- angles[3] = RAD2DEG * acos(f);
- } else
- angles[3] = 0.0;
-
- if (unitv[Y] < 0)
- angles[3] = 360.0 - angles[3];
-
- angles[4] *= RAD2DEG;
-}
-
-
-/**
- * general analyze function for polygonal faces.
- * Currently used for:
- * - arb8
- * - arbn
- * - ars
- *
- * returns:
- * - area in face->area
- * - print_faces_table() information in row
- * - sorts vertices in face->pts into ccw order
- */
-HIDDEN void
-analyze_poly_face(struct ged *gedp, struct poly_face *face, row_t *row)
-{
- fastf_t angles[5];
-
- findang(angles, face->plane_eqn);
-
- /* sort points */
- bg_3d_polygon_sort_ccw(face->npts, face->pts, face->plane_eqn);
- bg_3d_polygon_area(&face->area, face->npts, (const point_t *)face->pts);
-
- /* store face information for pretty printing */
- row->nfields = 8;
- row->fields[0].nchars = sprintf(row->fields[0].buf, "%4s", face->label);
- row->fields[1].nchars = sprintf(row->fields[1].buf, "%10.8f", angles[3]);
- row->fields[2].nchars = sprintf(row->fields[2].buf, "%10.8f", angles[4]);
- row->fields[3].nchars = sprintf(row->fields[3].buf, "%10.8f",
face->plane_eqn[X]);
- row->fields[4].nchars = sprintf(row->fields[4].buf, "%10.8f",
face->plane_eqn[Y]);
- row->fields[5].nchars = sprintf(row->fields[5].buf, "%10.8f",
face->plane_eqn[Z]);
- row->fields[6].nchars = sprintf(row->fields[6].buf, "%10.8f",
-
face->plane_eqn[W]*gedp->ged_wdbp->dbip->dbi_base2local);
- row->fields[7].nchars = sprintf(row->fields[7].buf, "%10.8f",
-
face->area*gedp->ged_wdbp->dbip->dbi_base2local*gedp->ged_wdbp->dbip->dbi_base2local);
-}
-
-
-HIDDEN void
-analyze_edge(struct ged *gedp, const int edge, const struct rt_arb_internal
*arb,
- const int type, row_t *row)
-{
- int a = nedge[type][edge*2];
- int b = nedge[type][edge*2+1];
-
- if (b == -1) {
- row->nfields = 0;
- return;
- }
-
- row->nfields = 2;
- row->fields[0].nchars = sprintf(row->fields[0].buf, "%d%d", a + 1, b + 1);
- row->fields[1].nchars = sprintf(row->fields[1].buf, "%10.8f",
- DIST_PNT_PNT(arb->pt[a],
arb->pt[b])*gedp->ged_wdbp->dbip->dbi_base2local);
-}
-
-
-HIDDEN void
-analyze_arb8(struct ged *gedp, const struct rt_db_internal *ip)
-{
- int i, type;
- int cgtype; /* COMGEOM arb type: # of vertices */
- table_t table; /* holds table data from child functions */
- fastf_t tot_vol = 0.0, tot_area = 0.0;
- point_t center_pt = VINIT_ZERO;
- struct poly_face face = POLY_FACE_INIT_ZERO;
- struct rt_arb_internal earb;
- struct rt_arb_internal *arb = (struct rt_arb_internal *)ip->idb_ptr;
- const int arb_faces[5][24] = rt_arb_faces;
- RT_ARB_CK_MAGIC(arb);
-
- /* find the specific arb type, in GIFT order. */
- if ((cgtype = rt_arb_std_type(ip, &gedp->ged_wdbp->wdb_tol)) == 0) {
- bu_vls_printf(gedp->ged_result_str, "analyze_arb: bad ARB\n");
- return;
- }
-
- type = cgtype - 4;
-
- /* to get formatting correct, we need to collect the actual string
- * lengths for each field BEFORE we start printing a table (fields
- * are allowed to overflow the stated printf field width) */
-
- /* TABLE 1 =========================================== */
- /* analyze each face, use center point of arb for reference */
- rt_arb_centroid(¢er_pt, ip);
-
- /* allocate pts array, maximum 4 verts per arb8 face */
- face.pts = (point_t *)bu_calloc(4, sizeof(point_t), "analyze_arb8: pts");
- /* allocate table rows, 12 rows needed for arb8 edges */
- table.rows = (row_t *)bu_calloc(12, sizeof(row_t), "analyze_arb8: rows");
-
- table.nrows = 0;
- for (face.npts = 0, i = 0; i < 6; face.npts = 0, i++) {
- int a, b, c, d; /* 4 indices to face vertices */
-
- a = arb_faces[type][i*4+0];
- b = arb_faces[type][i*4+1];
- c = arb_faces[type][i*4+2];
- d = arb_faces[type][i*4+3];
-
- if (a == -1) {
- table.rows[i].nfields = 0;
- continue;
- }
-
- /* find plane eqn for this face */
- if (bn_make_plane_3pnts(face.plane_eqn, arb->pt[a], arb->pt[b],
arb->pt[c], &gedp->ged_wdbp->wdb_tol) < 0) {
- bu_vls_printf(gedp->ged_result_str, "| %d%d%d%d | ***NOT A
PLANE*** |\n",
- a+1, b+1, c+1, d+1);
- /* this row has 1 special fields */
- table.rows[i].nfields = NOT_A_PLANE;
- continue;
- }
-
- ADD_PT(face, arb->pt[a]);
- ADD_PT(face, arb->pt[b]);
- ADD_PT(face, arb->pt[c]);
- ADD_PT(face, arb->pt[d]);
-
- /* The plane equations returned by bn_make_plane_3pnts above do
- * not necessarily point outward. Use the reference center
- * point for the arb and reverse direction for any errant planes.
- * This corrects the output rotation, fallback angles so that
- * they always give the outward pointing normal vector. */
- if (DIST_PNT_PLANE(center_pt, face.plane_eqn) > 0.0) {
- HREVERSE(face.plane_eqn, face.plane_eqn);
- }
-
- snprintf(face.label, sizeof(face.label), "%d", prface[type][i]);
-
- analyze_poly_face(gedp, &face, &(table.rows[i]));
- tot_area += face.area;
- table.nrows++;
- }
-
- /* and print it */
- print_faces_table(gedp, &table);
-
- /* TABLE 2 =========================================== */
- /* analyze each edge */
-
- /* blank line following previous table */
- bu_vls_printf(gedp->ged_result_str, "\n");
-
- /* set up the records for arb4's and arb6's */
- earb = *arb; /* struct copy */
- if (cgtype == 4) {
- VMOVE(earb.pt[3], earb.pt[4]);
- } else if (cgtype == 6) {
- VMOVE(earb.pt[5], earb.pt[6]);
- }
-
- table.nrows = 0;
- for (i = 0; i < 12; i++) {
- analyze_edge(gedp, i, &earb, type, &(table.rows[i]));
- if (nedge[type][i*2] == -1) {
- break;
- }
- table.nrows += 1;
- }
-
- print_edges_table(gedp, &table);
-
- /* TABLE 3 =========================================== */
- /* find the volume - break arb8 into 6 arb4s */
-
- if (OBJ[ID_ARB8].ft_volume)
- OBJ[ID_ARB8].ft_volume(&tot_vol, ip);
-
- print_volume_table(gedp,
- tot_vol
- * gedp->ged_wdbp->dbip->dbi_base2local
- * gedp->ged_wdbp->dbip->dbi_base2local
- * gedp->ged_wdbp->dbip->dbi_base2local,
- tot_area
- * gedp->ged_wdbp->dbip->dbi_base2local
- * gedp->ged_wdbp->dbip->dbi_base2local,
- tot_vol/GALLONS_TO_MM3
- );
-
- bu_free((char *)face.pts, "analyze_arb8: pts");
- bu_free((char *)table.rows, "analyze_arb8: rows");
-}
-
-
-HIDDEN void
-analyze_arbn(struct ged *gedp, const struct rt_db_internal *ip)
-{
- size_t i;
- fastf_t tot_vol = 0.0, tot_area = 0.0;
- table_t table;
- struct poly_face *faces;
- struct bu_vls tmpstr = BU_VLS_INIT_ZERO;
- struct rt_arbn_internal *aip = (struct rt_arbn_internal *)ip->idb_ptr;
- size_t *npts = (size_t *)bu_calloc(aip->neqn, sizeof(size_t),
"analyze_arbn: npts");
- point_t **tmp_pts = (point_t **)bu_calloc(aip->neqn, sizeof(point_t *),
"analyze_arbn: tmp_pts");
- plane_t *eqs= (plane_t *)bu_calloc(aip->neqn, sizeof(plane_t),
"analyze_arbn: eqs");
-
- /* allocate array of face structs */
- faces = (struct poly_face *)bu_calloc(aip->neqn, sizeof(struct poly_face),
"analyze_arbn: faces");
- for (i = 0; i < aip->neqn; i++) {
- HMOVE(faces[i].plane_eqn, aip->eqn[i]);
- VUNITIZE(faces[i].plane_eqn);
- /* allocate array of pt structs, max number of verts per faces = (# of
faces) - 1 */
- faces[i].pts = (point_t *)bu_calloc(aip->neqn - 1, sizeof(point_t),
"analyze_arbn: pts");
- tmp_pts[i] = faces[i].pts;
- HMOVE(eqs[i], faces[i].plane_eqn);
- }
- /* allocate table rows, 1 row per plane eqn */
- table.rows = (row_t *)bu_calloc(aip->neqn, sizeof(row_t), "analyze_arbn:
rows");
- table.nrows = aip->neqn;
-
- bg_3d_polygon_make_pnts_planes(npts, tmp_pts, aip->neqn, (const plane_t
*)eqs);
-
- for (i = 0; i < aip->neqn; i++) {
- vect_t tmp;
- bu_vls_sprintf(&tmpstr, "%4zu", i);
- snprintf(faces[i].label, sizeof(faces[i].label), "%s",
bu_vls_addr(&tmpstr));
-
- faces[i].npts = npts[i];
-
- /* calculate surface area */
- analyze_poly_face(gedp, &faces[i], &table.rows[i]);
- tot_area += faces[i].area;
-
- /* calculate volume */
- VSCALE(tmp, faces[i].plane_eqn, faces[i].area);
- tot_vol += VDOT(faces[i].pts[0], tmp);
- }
- tot_vol /= 3.0;
-
- print_faces_table(gedp, &table);
- print_volume_table(gedp,
- tot_vol
- * gedp->ged_wdbp->dbip->dbi_base2local
- * gedp->ged_wdbp->dbip->dbi_base2local
- * gedp->ged_wdbp->dbip->dbi_base2local,
- tot_area
- * gedp->ged_wdbp->dbip->dbi_base2local
- * gedp->ged_wdbp->dbip->dbi_base2local,
- tot_vol/GALLONS_TO_MM3
- );
-
- for (i = 0; i < aip->neqn; i++) {
- bu_free((char *)faces[i].pts, "analyze_arbn: pts");
- }
- bu_free((char *)faces, "analyze_arbn: faces");
- bu_free((char *)table.rows, "analyze_arbn: rows");
- bu_free((char *)tmp_pts, "analyze_arbn: tmp_pts");
- bu_free((char *)npts, "analyze_arbn: npts");
- bu_free((char *)eqs, "analyze_arbn: eqs");
- bu_vls_free(&tmpstr);
-}
-
-
-#define ARS_PT(ii, jj) (&arip->curves[i+(ii)][(j+(jj))*ELEMENTS_PER_VECT])
-
-HIDDEN void
-analyze_ars(struct ged *gedp, const struct rt_db_internal *ip)
-{
- size_t i, j, k;
- size_t nfaces = 0;
- fastf_t tot_area = 0.0, tot_vol = 0.0;
- table_t table;
- plane_t old_plane = HINIT_ZERO;
- struct bu_vls tmpstr = BU_VLS_INIT_ZERO;
- struct poly_face face = POLY_FACE_INIT_ZERO;
- struct rt_ars_internal *arip = (struct rt_ars_internal *)ip->idb_ptr;
- RT_ARS_CK_MAGIC(arip);
-
- /* allocate pts array, max 3 pts per triangular face */
- face.pts = (point_t *)bu_calloc(3, sizeof(point_t), "analyze_ars: pts");
- /* allocate table rows, probably overestimating the number of rows needed
*/
- table.rows = (row_t *)bu_calloc((arip->ncurves - 1) * 2 *
arip->pts_per_curve, sizeof(row_t), "analyze_ars: rows");
-
- k = arip->pts_per_curve - 2;
- for (i = 0; i < arip->ncurves - 1; i++) {
- int double_ended = k != 1 &&
VEQUAL(&arip->curves[i][ELEMENTS_PER_VECT], &arip->curves[i][k *
ELEMENTS_PER_VECT]);
-
- for (j = 0; j < arip->pts_per_curve; j++) {
- vect_t tmp;
-
- if (double_ended && i != 0 && (j == 0 || j == k || j ==
arip->pts_per_curve - 1)) continue;
-
- /* first triangular face, make sure it's not a duplicate */
- if (bn_make_plane_3pnts(face.plane_eqn, ARS_PT(0, 0), ARS_PT(1, 1),
ARS_PT(0, 1), &gedp->ged_wdbp->wdb_tol) == 0
- && !HEQUAL(old_plane, face.plane_eqn)) {
- HMOVE(old_plane, face.plane_eqn);
- ADD_PT(face, ARS_PT(0, 1));
- ADD_PT(face, ARS_PT(0, 0));
- ADD_PT(face, ARS_PT(1, 1));
-
- bu_vls_sprintf(&tmpstr, "%zu%zu", i, j);
- snprintf(face.label, sizeof(face.label), "%s",
bu_vls_addr(&tmpstr));
-
- /* surface area */
- analyze_poly_face(gedp, &face, &(table.rows[nfaces]));
- tot_area += face.area;
-
- /* volume */
- VSCALE(tmp, face.plane_eqn, face.area);
- tot_vol += fabs(VDOT(face.pts[0], tmp));
-
- face.npts = 0;
- nfaces++;
- }
-
- /* second triangular face, make sure it's not a duplicate */
- if (bn_make_plane_3pnts(face.plane_eqn, ARS_PT(1, 0), ARS_PT(1, 1),
ARS_PT(0, 0), &gedp->ged_wdbp->wdb_tol) == 0
- && !HEQUAL(old_plane, face.plane_eqn)) {
- HMOVE(old_plane, face.plane_eqn);
- ADD_PT(face, ARS_PT(1, 0));
- ADD_PT(face, ARS_PT(0, 0));
- ADD_PT(face, ARS_PT(1, 1));
-
- bu_vls_sprintf(&tmpstr, "%zu%zu", i, j);
- snprintf(face.label, sizeof(face.label), "%s",
bu_vls_addr(&tmpstr));
-
- analyze_poly_face(gedp, &face, &table.rows[nfaces]);
- tot_area += face.area;
-
- VSCALE(tmp, face.plane_eqn, face.area);
- tot_vol += fabs(VDOT(face.pts[0], tmp));
-
- face.npts = 0;
- nfaces++;
- }
- }
- }
- tot_vol /= 3.0;
- table.nrows = nfaces;
-
- print_faces_table(gedp, &table);
- print_volume_table(gedp,
- tot_vol
- * gedp->ged_wdbp->dbip->dbi_base2local
- * gedp->ged_wdbp->dbip->dbi_base2local
- * gedp->ged_wdbp->dbip->dbi_base2local,
- tot_area
- * gedp->ged_wdbp->dbip->dbi_base2local
- * gedp->ged_wdbp->dbip->dbi_base2local,
- tot_vol/GALLONS_TO_MM3
- );
-
- bu_free((char *)face.pts, "analyze_ars: pts");
- bu_free((char *)table.rows, "analyze_ars: rows");
- bu_vls_free(&tmpstr);
-}
-
-
-#define PROLATE 1
-#define OBLATE 2
-
-HIDDEN void
-analyze_superell(struct ged *gedp, const struct rt_db_internal *ip)
-{
- struct rt_superell_internal *superell = (struct rt_superell_internal
*)ip->idb_ptr;
- fastf_t ma, mb, mc;
- fastf_t ecc, major_mag, minor_mag;
- fastf_t vol, sur_area;
- int type;
-
- RT_SUPERELL_CK_MAGIC(superell);
-
- ma = MAGNITUDE(superell->a);
- mb = MAGNITUDE(superell->b);
- mc = MAGNITUDE(superell->c);
-
- type = 0;
-
- vol = 4.0 * M_PI * ma * mb * mc / 3.0;
-
- if (fabs(ma-mb) < .00001 && fabs(mb-mc) < .00001) {
- /* have a sphere */
- sur_area = 4.0 * M_PI * ma * ma;
- goto print_results;
- }
- if (fabs(ma-mb) < .00001) {
- /* A == B */
- if (mc > ma) {
- /* oblate spheroid */
- type = OBLATE;
- major_mag = mc;
- minor_mag = ma;
- } else {
- /* prolate spheroid */
- type = PROLATE;
- major_mag = ma;
- minor_mag = mc;
- }
- } else
- if (fabs(ma-mc) < .00001) {
- /* A == C */
- if (mb > ma) {
- /* oblate spheroid */
- type = OBLATE;
- major_mag = mb;
- minor_mag = ma;
- } else {
- /* prolate spheroid */
- type = PROLATE;
- major_mag = ma;
- minor_mag = mb;
- }
- } else
- if (fabs(mb-mc) < .00001) {
- /* B == C */
- if (ma > mb) {
- /* oblate spheroid */
- type = OBLATE;
- major_mag = ma;
- minor_mag = mb;
- } else {
- /* prolate spheroid */
- type = PROLATE;
- major_mag = mb;
- minor_mag = ma;
- }
- } else {
- bu_vls_printf(gedp->ged_result_str, " Cannot find surface
area\n");
- return;
- }
- ecc = sqrt(major_mag*major_mag - minor_mag*minor_mag) / major_mag;
- if (type == PROLATE) {
- sur_area = M_2PI * minor_mag * minor_mag +
- (M_2PI * (major_mag*minor_mag/ecc) * asin(ecc));
- } else {
- /* type == OBLATE */
- sur_area = M_2PI * major_mag * major_mag +
- (M_PI * (minor_mag*minor_mag/ecc) * log((1.0+ecc)/(1.0-ecc)));
- }
-
-print_results:
- print_volume_table(gedp,
- vol
- * gedp->ged_wdbp->dbip->dbi_base2local
- * gedp->ged_wdbp->dbip->dbi_base2local
- * gedp->ged_wdbp->dbip->dbi_base2local,
- sur_area
- * gedp->ged_wdbp->dbip->dbi_base2local
- * gedp->ged_wdbp->dbip->dbi_base2local,
- vol/GALLONS_TO_MM3
- );
-}
-
-
-HIDDEN void
-analyze_sketch(struct ged *gedp, const struct rt_db_internal *ip)
-{
- fastf_t area = -1;
- point_t centroid;
-
- if (OBJ[ID_SKETCH].ft_surf_area)
- OBJ[ID_SKETCH].ft_surf_area(&area, ip);
-
- if (area > 0.0) {
- bu_vls_printf(gedp->ged_result_str, "\nTotal Area: %10.8f",
- area
- * gedp->ged_wdbp->dbip->dbi_local2base
- * gedp->ged_wdbp->dbip->dbi_local2base
- );
- }
-
- if (OBJ[ID_SKETCH].ft_centroid) {
- OBJ[ID_SKETCH].ft_centroid(¢roid, ip);
- bu_vls_printf(gedp->ged_result_str, "\n Centroid: (%g, %g, %g)\n",
- centroid[X] * gedp->ged_wdbp->dbip->dbi_base2local,
- centroid[Y] * gedp->ged_wdbp->dbip->dbi_base2local,
- centroid[Z] * gedp->ged_wdbp->dbip->dbi_base2local);
- }
-}
-
-
-/**
- * Analyze command - prints loads of info about a solid
- * Format: analyze [name]
- * if 'name' is missing use solid being edited
- */
-
-/* Analyze solid in internal form */
-HIDDEN void
-analyze_do(struct ged *gedp, const struct rt_db_internal *ip)
-{
- /* XXX Could give solid name, and current units, here */
-
- switch (ip->idb_type) {
-
- case ID_ARB8:
- analyze_arb8(gedp, ip);
- break;
-
- case ID_BOT:
- analyze_general(gedp, ip);
- break;
-
- case ID_ARBN:
- analyze_arbn(gedp, ip);
- break;
-
- case ID_ARS:
- analyze_ars(gedp, ip);
- break;
-
- case ID_TGC:
- analyze_general(gedp, ip);
- break;
-
- case ID_ELL:
- analyze_general(gedp, ip);
- break;
-
- case ID_TOR:
- analyze_general(gedp, ip);
- break;
-
- case ID_RPC:
- analyze_general(gedp, ip);
- break;
-
- case ID_ETO:
- analyze_general(gedp, ip);
- break;
-
- case ID_EPA:
- analyze_general(gedp, ip);
- break;
-
- case ID_PARTICLE:
- analyze_general(gedp, ip);
- break;
-
- case ID_SUPERELL:
- analyze_superell(gedp, ip);
- break;
-
- case ID_SKETCH:
- analyze_sketch(gedp, ip);
- break;
-
- case ID_HYP:
- analyze_general(gedp, ip);
- break;
-
- case ID_PIPE:
- analyze_general(gedp, ip);
- break;
-
- case ID_VOL:
- analyze_general(gedp, ip);
- break;
-
- case ID_EXTRUDE:
- analyze_general(gedp, ip);
- break;
-
- case ID_RHC:
- analyze_general(gedp, ip);
- break;
-
- default:
- bu_vls_printf(gedp->ged_result_str, "\nanalyze: unable to process
%s solid\n",
- OBJ[ip->idb_type].ft_name);
- break;
- }
-}
-
-
-int
-ged_analyze_core(struct ged *gedp, int argc, const char *argv[])
-{
- struct directory *ndp;
- int i;
- struct rt_db_internal intern;
- static const char *usage = "object(s)";
-
- 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", argv[0], usage);
- return GED_HELP;
- }
-
- /* use the names that were input */
- for (i = 1; i < argc; i++) {
- if ((ndp = db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) ==
RT_DIR_NULL)
- continue;
-
- GED_DB_GET_INTERNAL(gedp, &intern, ndp, bn_mat_identity,
&rt_uniresource, GED_ERROR);
-
- _ged_do_list(gedp, ndp, 1);
- analyze_do(gedp, &intern);
- rt_db_free_internal(&intern);
- }
-
- return GED_OK;
-}
-
-
-#ifdef GED_PLUGIN
-#include "../include/plugin.h"
-struct ged_cmd_impl analyze_cmd_impl = {
- "analyze",
- ged_analyze_core,
- GED_CMD_DEFAULT
-};
-
-const struct ged_cmd analyze_cmd = { &analyze_cmd_impl };
-const struct ged_cmd *analyze_cmds[] = { &analyze_cmd, NULL };
-
-static const struct ged_plugin pinfo = { GED_API, analyze_cmds, 1 };
-
-COMPILER_DLLEXPORT const struct ged_plugin *ged_plugin_info()
-{
- return &pinfo;
-}
-#endif /* GED_PLUGIN */
-
-/*
- * Local Variables:
- * mode: C
- * tab-width: 8
- * indent-tabs-mode: t
- * c-file-style: "stroustrup"
- * End:
- * ex: shiftwidth=4 tabstop=8
- */
Modified: brlcad/branches/analyze_cmd/src/libged/analyze/analyze.cpp
===================================================================
--- brlcad/branches/analyze_cmd/src/libged/analyze/analyze.cpp 2020-08-19
15:26:00 UTC (rev 76850)
+++ brlcad/branches/analyze_cmd/src/libged/analyze/analyze.cpp 2020-08-19
17:50:31 UTC (rev 76851)
@@ -66,6 +66,101 @@
return 0;
}
+/* Analyze solid in internal form.
+ * TODO - this switch table probably indicates this should
+ * be a functab callback... */
+/**
+ * TODO: primitives that still need implementing
+ * ehy
+ * metaball
+ * nmg
+ */
+static void
+analyze_do_summary(struct ged *gedp, const struct rt_db_internal *ip)
+{
+ /* XXX Could give solid name, and current units, here */
+
+ switch (ip->idb_type) {
+
+ case ID_ARB8:
+ analyze_arb8(gedp, ip);
+ break;
+
+ case ID_BOT:
+ analyze_general(gedp, ip);
+ break;
+
+ case ID_ARBN:
+ analyze_arbn(gedp, ip);
+ break;
+
+ case ID_ARS:
+ analyze_ars(gedp, ip);
+ break;
+
+ case ID_TGC:
+ analyze_general(gedp, ip);
+ break;
+
+ case ID_ELL:
+ analyze_general(gedp, ip);
+ break;
+
+ case ID_TOR:
+ analyze_general(gedp, ip);
+ break;
+
+ case ID_RPC:
+ analyze_general(gedp, ip);
+ break;
+
+ case ID_ETO:
+ analyze_general(gedp, ip);
+ break;
+
+ case ID_EPA:
+ analyze_general(gedp, ip);
+ break;
+
+ case ID_PARTICLE:
+ analyze_general(gedp, ip);
+ break;
+
+ case ID_SUPERELL:
+ analyze_superell(gedp, ip);
+ break;
+
+ case ID_SKETCH:
+ analyze_sketch(gedp, ip);
+ break;
+
+ case ID_HYP:
+ analyze_general(gedp, ip);
+ break;
+
+ case ID_PIPE:
+ analyze_general(gedp, ip);
+ break;
+
+ case ID_VOL:
+ analyze_general(gedp, ip);
+ break;
+
+ case ID_EXTRUDE:
+ analyze_general(gedp, ip);
+ break;
+
+ case ID_RHC:
+ analyze_general(gedp, ip);
+ break;
+
+ default:
+ bu_vls_printf(gedp->ged_result_str, "\nanalyze: unable to process
%s solid\n",
+ OBJ[ip->idb_type].ft_name);
+ break;
+ }
+}
+
extern "C" int
_analyze_cmd_summarize(void *bs, int argc, const char **argv)
{
@@ -76,13 +171,34 @@
}
struct _ged_analyze_info *gc = (struct _ged_analyze_info *)bs;
+ struct ged *gedp = gc->gedp;
+ struct rt_db_internal intern;
argc--; argv++;
- if (argc != 2) {
+ if (!argc) {
bu_vls_printf(gc->gedp->ged_result_str, "%s\n", usage_string);
return GED_ERROR;
}
+ 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);
+
+ /* use the names that were input */
+ for (int i = 0; i < argc; i++) {
+ struct directory *ndp = db_lookup(gedp->ged_wdbp->dbip, argv[i],
LOOKUP_NOISY);
+ if (ndp == RT_DIR_NULL)
+ continue;
+
+ GED_DB_GET_INTERNAL(gedp, &intern, ndp, bn_mat_identity,
&rt_uniresource, GED_ERROR);
+
+ _ged_do_list(gedp, ndp, 1);
+ analyze_do_summary(gedp, &intern);
+ rt_db_free_internal(&intern);
+ }
+
return GED_OK;
}
@@ -157,9 +273,6 @@
// Clear results
bu_vls_trunc(gedp->ged_result_str, 0);
- // We know we're the brep command - start processing args
- argc--; argv++;
-
// See if we have any high level options set
struct bu_opt_desc d[3];
BU_OPT(d[0], "h", "help", "", NULL, &help,
"Print help");
@@ -168,7 +281,7 @@
gc.gopts = d;
- if (!argc) {
+ if (argc == 1) {
_analyze_cmd_help(&gc, 0, NULL);
return GED_OK;
}
@@ -175,7 +288,7 @@
// High level options are only defined prior to the subcommand
int cmd_pos = -1;
- for (int i = 0; i < argc; i++) {
+ for (int i = 1; i < argc; i++) {
if (bu_cmd_valid(_analyze_cmds, argv[i]) == BRLCAD_OK) {
cmd_pos = i;
break;
@@ -197,18 +310,19 @@
return GED_OK;
}
- // Must have a subcommand
- if (cmd_pos == -1) {
- bu_vls_printf(gedp->ged_result_str, ": no valid subcommand
specified\n");
- _analyze_cmd_help(&gc, 0, NULL);
- return GED_ERROR;
+ // Jump the processing past any options specified. If we don't have a
+ // subcommand, assume all args are geometry objects and the command mode is
+ // summarize. This will get us the old behavior, except in the case where
+ // we happen to have an object with a name that matches a subcommand of
+ // analyze. In that case, the full "analyze summarize objname" is needed.
+ const char *scmd = "summarize";
+ if (cmd_pos != -1) {
+ argc = argc - cmd_pos;
+ argv = &argv[cmd_pos];
+ } else {
+ argv[0] = scmd;
}
-
- // Jump the processing past any options specified
- argc = argc - cmd_pos;
- argv = &argv[cmd_pos];
-
int ret;
if (bu_cmd(_analyze_cmds, argc, argv, 0, (void *)&gc, &ret) == BRLCAD_OK) {
return ret;
Added: brlcad/branches/analyze_cmd/src/libged/analyze/arb8.cpp
===================================================================
--- brlcad/branches/analyze_cmd/src/libged/analyze/arb8.cpp
(rev 0)
+++ brlcad/branches/analyze_cmd/src/libged/analyze/arb8.cpp 2020-08-19
17:50:31 UTC (rev 76851)
@@ -0,0 +1,209 @@
+/* A R B 8 . C P P
+ * BRL-CAD
+ *
+ * Copyright (c) 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 arb8.cpp
+ *
+ * Brief description
+ *
+ */
+
+#include "common.h"
+
+#include "vmath.h"
+
+#include "bg/polygon.h"
+#include "rt/arb_edit.h"
+#include "rt/geom.h"
+#include "ged/defines.h"
+#include "../ged_private.h"
+#include "./ged_analyze.h"
+
+/* edge definition array */
+static const int nedge[5][24] = {
+ {0, 1, 1, 2, 2, 0, 0, 3, 3, 2, 1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1}, /* ARB4 */
+ {0, 1, 1, 2, 2, 3, 0, 3, 0, 4, 1, 4, 2, 4, 3, 4, -1, -1, -1, -1, -1, -1,
-1, -1}, /* ARB5 */
+ {0, 1, 1, 2, 2, 3, 0, 3, 0, 4, 1, 4, 2, 5, 3, 5, 4, 5, -1, -1, -1, -1, -1,
-1}, /* ARB6 */
+ {0, 1, 1, 2, 2, 3, 0, 3, 0, 4, 3, 4, 1, 5, 2, 6, 4, 5, 5, 6, 4, 6, -1,
-1}, /* ARB7 */
+ {0, 1, 1, 2, 2, 3, 0, 3, 0, 4, 4, 5, 1, 5, 5, 6, 6, 7, 4, 7, 3, 7, 2, 6},
/* ARB8 */
+};
+
+/* ARB face printout array */
+static const int prface[5][6] = {
+ {123, 124, 234, 134, -111, -111}, /* ARB4 */
+ {1234, 125, 235, 345, 145, -111}, /* ARB5 */
+ {1234, 2365, 1564, 512, 634, -111}, /* ARB6 */
+ {1234, 567, 145, 2376, 1265, 4375}, /* ARB7 */
+ {1234, 5678, 1584, 2376, 1265, 4378}, /* ARB8 */
+};
+
+void
+analyze_edge(struct ged *gedp, const int edge, const struct rt_arb_internal
*arb,
+ const int type, row_t *row)
+{
+ int a = nedge[type][edge*2];
+ int b = nedge[type][edge*2+1];
+
+ if (b == -1) {
+ row->nfields = 0;
+ return;
+ }
+
+ row->nfields = 2;
+ row->fields[0].nchars = sprintf(row->fields[0].buf, "%d%d", a + 1, b + 1);
+ row->fields[1].nchars = sprintf(row->fields[1].buf, "%10.8f",
+ DIST_PNT_PNT(arb->pt[a],
arb->pt[b])*gedp->ged_wdbp->dbip->dbi_base2local);
+}
+
+
+
+void
+analyze_arb8(struct ged *gedp, const struct rt_db_internal *ip)
+{
+ int i, type;
+ int cgtype; /* COMGEOM arb type: # of vertices */
+ table_t table; /* holds table data from child functions */
+ fastf_t tot_vol = 0.0, tot_area = 0.0;
+ point_t center_pt = VINIT_ZERO;
+ struct poly_face face = POLY_FACE_INIT_ZERO;
+ struct rt_arb_internal earb;
+ struct rt_arb_internal *arb = (struct rt_arb_internal *)ip->idb_ptr;
+ const int arb_faces[5][24] = rt_arb_faces;
+ RT_ARB_CK_MAGIC(arb);
+
+ /* find the specific arb type, in GIFT order. */
+ if ((cgtype = rt_arb_std_type(ip, &gedp->ged_wdbp->wdb_tol)) == 0) {
+ bu_vls_printf(gedp->ged_result_str, "analyze_arb: bad ARB\n");
+ return;
+ }
+
+ type = cgtype - 4;
+
+ /* to get formatting correct, we need to collect the actual string
+ * lengths for each field BEFORE we start printing a table (fields
+ * are allowed to overflow the stated printf field width) */
+
+ /* TABLE 1 =========================================== */
+ /* analyze each face, use center point of arb for reference */
+ rt_arb_centroid(¢er_pt, ip);
+
+ /* allocate pts array, maximum 4 verts per arb8 face */
+ face.pts = (point_t *)bu_calloc(4, sizeof(point_t), "analyze_arb8: pts");
+ /* allocate table rows, 12 rows needed for arb8 edges */
+ table.rows = (row_t *)bu_calloc(12, sizeof(row_t), "analyze_arb8: rows");
+
+ table.nrows = 0;
+ for (face.npts = 0, i = 0; i < 6; face.npts = 0, i++) {
+ int a, b, c, d; /* 4 indices to face vertices */
+
+ a = arb_faces[type][i*4+0];
+ b = arb_faces[type][i*4+1];
+ c = arb_faces[type][i*4+2];
+ d = arb_faces[type][i*4+3];
+
+ if (a == -1) {
+ table.rows[i].nfields = 0;
+ continue;
+ }
+
+ /* find plane eqn for this face */
+ if (bn_make_plane_3pnts(face.plane_eqn, arb->pt[a], arb->pt[b],
arb->pt[c], &gedp->ged_wdbp->wdb_tol) < 0) {
+ bu_vls_printf(gedp->ged_result_str, "| %d%d%d%d | ***NOT A
PLANE*** |\n",
+ a+1, b+1, c+1, d+1);
+ /* this row has 1 special fields */
+ table.rows[i].nfields = NOT_A_PLANE;
+ continue;
+ }
+
+ ADD_PT(face, arb->pt[a]);
+ ADD_PT(face, arb->pt[b]);
+ ADD_PT(face, arb->pt[c]);
+ ADD_PT(face, arb->pt[d]);
+
+ /* The plane equations returned by bn_make_plane_3pnts above do
+ * not necessarily point outward. Use the reference center
+ * point for the arb and reverse direction for any errant planes.
+ * This corrects the output rotation, fallback angles so that
+ * they always give the outward pointing normal vector. */
+ if (DIST_PNT_PLANE(center_pt, face.plane_eqn) > 0.0) {
+ HREVERSE(face.plane_eqn, face.plane_eqn);
+ }
+
+ snprintf(face.label, sizeof(face.label), "%d", prface[type][i]);
+
+ analyze_poly_face(gedp, &face, &(table.rows[i]));
+ tot_area += face.area;
+ table.nrows++;
+ }
+
+ /* and print it */
+ print_faces_table(gedp, &table);
+
+ /* TABLE 2 =========================================== */
+ /* analyze each edge */
+
+ /* blank line following previous table */
+ bu_vls_printf(gedp->ged_result_str, "\n");
+
+ /* set up the records for arb4's and arb6's */
+ earb = *arb; /* struct copy */
+ if (cgtype == 4) {
+ VMOVE(earb.pt[3], earb.pt[4]);
+ } else if (cgtype == 6) {
+ VMOVE(earb.pt[5], earb.pt[6]);
+ }
+
+ table.nrows = 0;
+ for (i = 0; i < 12; i++) {
+ analyze_edge(gedp, i, &earb, type, &(table.rows[i]));
+ if (nedge[type][i*2] == -1) {
+ break;
+ }
+ table.nrows += 1;
+ }
+
+ print_edges_table(gedp, &table);
+
+ /* TABLE 3 =========================================== */
+ /* find the volume - break arb8 into 6 arb4s */
+
+ if (OBJ[ID_ARB8].ft_volume)
+ OBJ[ID_ARB8].ft_volume(&tot_vol, ip);
+
+ print_volume_table(gedp,
+ tot_vol
+ * gedp->ged_wdbp->dbip->dbi_base2local
+ * gedp->ged_wdbp->dbip->dbi_base2local
+ * gedp->ged_wdbp->dbip->dbi_base2local,
+ tot_area
+ * gedp->ged_wdbp->dbip->dbi_base2local
+ * gedp->ged_wdbp->dbip->dbi_base2local,
+ tot_vol/GALLONS_TO_MM3
+ );
+
+ bu_free((char *)face.pts, "analyze_arb8: pts");
+ bu_free((char *)table.rows, "analyze_arb8: rows");
+}
+// Local Variables:
+// tab-width: 8
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: t
+// c-file-style: "stroustrup"
+// End:
+// ex: shiftwidth=4 tabstop=8
Property changes on: brlcad/branches/analyze_cmd/src/libged/analyze/arb8.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: brlcad/branches/analyze_cmd/src/libged/analyze/arbn.cpp
===================================================================
--- brlcad/branches/analyze_cmd/src/libged/analyze/arbn.cpp
(rev 0)
+++ brlcad/branches/analyze_cmd/src/libged/analyze/arbn.cpp 2020-08-19
17:50:31 UTC (rev 76851)
@@ -0,0 +1,112 @@
+/* A R B N . C P P
+ * BRL-CAD
+ *
+ * Copyright (c) 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 arbn.cpp
+ *
+ * Brief description
+ *
+ */
+
+#include "common.h"
+
+#include "vmath.h"
+
+#include "rt/geom.h"
+#include "ged/defines.h"
+#include "../ged_private.h"
+#include "./ged_analyze.h"
+
+void
+analyze_arbn(struct ged *gedp, const struct rt_db_internal *ip)
+{
+ size_t i;
+ fastf_t tot_vol = 0.0, tot_area = 0.0;
+ table_t table;
+ struct poly_face *faces;
+ struct bu_vls tmpstr = BU_VLS_INIT_ZERO;
+ struct rt_arbn_internal *aip = (struct rt_arbn_internal *)ip->idb_ptr;
+ size_t *npts = (size_t *)bu_calloc(aip->neqn, sizeof(size_t),
"analyze_arbn: npts");
+ point_t **tmp_pts = (point_t **)bu_calloc(aip->neqn, sizeof(point_t *),
"analyze_arbn: tmp_pts");
+ plane_t *eqs= (plane_t *)bu_calloc(aip->neqn, sizeof(plane_t),
"analyze_arbn: eqs");
+
+ /* allocate array of face structs */
+ faces = (struct poly_face *)bu_calloc(aip->neqn, sizeof(struct poly_face),
"analyze_arbn: faces");
+ for (i = 0; i < aip->neqn; i++) {
+ HMOVE(faces[i].plane_eqn, aip->eqn[i]);
+ VUNITIZE(faces[i].plane_eqn);
+ /* allocate array of pt structs, max number of verts per faces = (# of
faces) - 1 */
+ faces[i].pts = (point_t *)bu_calloc(aip->neqn - 1, sizeof(point_t),
"analyze_arbn: pts");
+ tmp_pts[i] = faces[i].pts;
+ HMOVE(eqs[i], faces[i].plane_eqn);
+ }
+ /* allocate table rows, 1 row per plane eqn */
+ table.rows = (row_t *)bu_calloc(aip->neqn, sizeof(row_t), "analyze_arbn:
rows");
+ table.nrows = aip->neqn;
+
+ bg_3d_polygon_make_pnts_planes(npts, tmp_pts, aip->neqn, (const plane_t
*)eqs);
+
+ for (i = 0; i < aip->neqn; i++) {
+ vect_t tmp;
+ bu_vls_sprintf(&tmpstr, "%4zu", i);
+ snprintf(faces[i].label, sizeof(faces[i].label), "%s",
bu_vls_addr(&tmpstr));
+
+ faces[i].npts = npts[i];
+
+ /* calculate surface area */
+ analyze_poly_face(gedp, &faces[i], &table.rows[i]);
+ tot_area += faces[i].area;
+
+ /* calculate volume */
+ VSCALE(tmp, faces[i].plane_eqn, faces[i].area);
+ tot_vol += VDOT(faces[i].pts[0], tmp);
+ }
+ tot_vol /= 3.0;
+
+ print_faces_table(gedp, &table);
+ print_volume_table(gedp,
+ tot_vol
+ * gedp->ged_wdbp->dbip->dbi_base2local
+ * gedp->ged_wdbp->dbip->dbi_base2local
+ * gedp->ged_wdbp->dbip->dbi_base2local,
+ tot_area
+ * gedp->ged_wdbp->dbip->dbi_base2local
+ * gedp->ged_wdbp->dbip->dbi_base2local,
+ tot_vol/GALLONS_TO_MM3
+ );
+
+ for (i = 0; i < aip->neqn; i++) {
+ bu_free((char *)faces[i].pts, "analyze_arbn: pts");
+ }
+ bu_free((char *)faces, "analyze_arbn: faces");
+ bu_free((char *)table.rows, "analyze_arbn: rows");
+ bu_free((char *)tmp_pts, "analyze_arbn: tmp_pts");
+ bu_free((char *)npts, "analyze_arbn: npts");
+ bu_free((char *)eqs, "analyze_arbn: eqs");
+ bu_vls_free(&tmpstr);
+}
+
+
+// Local Variables:
+// tab-width: 8
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: t
+// c-file-style: "stroustrup"
+// End:
+// ex: shiftwidth=4 tabstop=8
Property changes on: brlcad/branches/analyze_cmd/src/libged/analyze/arbn.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: brlcad/branches/analyze_cmd/src/libged/analyze/ars.cpp
===================================================================
--- brlcad/branches/analyze_cmd/src/libged/analyze/ars.cpp
(rev 0)
+++ brlcad/branches/analyze_cmd/src/libged/analyze/ars.cpp 2020-08-19
17:50:31 UTC (rev 76851)
@@ -0,0 +1,138 @@
+/* A R S . C P P
+ * BRL-CAD
+ *
+ * Copyright (c) 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 ars.cpp
+ *
+ * Brief description
+ *
+ */
+
+#include "common.h"
+
+#include "vmath.h"
+
+#include "rt/geom.h"
+#include "ged/defines.h"
+#include "../ged_private.h"
+#include "./ged_analyze.h"
+
+#define ARS_PT(ii, jj) (&arip->curves[i+(ii)][(j+(jj))*ELEMENTS_PER_VECT])
+
+void
+analyze_ars(struct ged *gedp, const struct rt_db_internal *ip)
+{
+ size_t i, j, k;
+ size_t nfaces = 0;
+ fastf_t tot_area = 0.0, tot_vol = 0.0;
+ table_t table;
+ plane_t old_plane = HINIT_ZERO;
+ struct bu_vls tmpstr = BU_VLS_INIT_ZERO;
+ struct poly_face face = POLY_FACE_INIT_ZERO;
+ struct rt_ars_internal *arip = (struct rt_ars_internal *)ip->idb_ptr;
+ RT_ARS_CK_MAGIC(arip);
+
+ /* allocate pts array, max 3 pts per triangular face */
+ face.pts = (point_t *)bu_calloc(3, sizeof(point_t), "analyze_ars: pts");
+ /* allocate table rows, probably overestimating the number of rows needed
*/
+ table.rows = (row_t *)bu_calloc((arip->ncurves - 1) * 2 *
arip->pts_per_curve, sizeof(row_t), "analyze_ars: rows");
+
+ k = arip->pts_per_curve - 2;
+ for (i = 0; i < arip->ncurves - 1; i++) {
+ int double_ended = k != 1 &&
VEQUAL(&arip->curves[i][ELEMENTS_PER_VECT], &arip->curves[i][k *
ELEMENTS_PER_VECT]);
+
+ for (j = 0; j < arip->pts_per_curve; j++) {
+ vect_t tmp;
+
+ if (double_ended && i != 0 && (j == 0 || j == k || j ==
arip->pts_per_curve - 1)) continue;
+
+ /* first triangular face, make sure it's not a duplicate */
+ if (bn_make_plane_3pnts(face.plane_eqn, ARS_PT(0, 0), ARS_PT(1, 1),
ARS_PT(0, 1), &gedp->ged_wdbp->wdb_tol) == 0
+ && !HEQUAL(old_plane, face.plane_eqn)) {
+ HMOVE(old_plane, face.plane_eqn);
+ ADD_PT(face, ARS_PT(0, 1));
+ ADD_PT(face, ARS_PT(0, 0));
+ ADD_PT(face, ARS_PT(1, 1));
+
+ bu_vls_sprintf(&tmpstr, "%zu%zu", i, j);
+ snprintf(face.label, sizeof(face.label), "%s",
bu_vls_addr(&tmpstr));
+
+ /* surface area */
+ analyze_poly_face(gedp, &face, &(table.rows[nfaces]));
+ tot_area += face.area;
+
+ /* volume */
+ VSCALE(tmp, face.plane_eqn, face.area);
+ tot_vol += fabs(VDOT(face.pts[0], tmp));
+
+ face.npts = 0;
+ nfaces++;
+ }
+
+ /* second triangular face, make sure it's not a duplicate */
+ if (bn_make_plane_3pnts(face.plane_eqn, ARS_PT(1, 0), ARS_PT(1, 1),
ARS_PT(0, 0), &gedp->ged_wdbp->wdb_tol) == 0
+ && !HEQUAL(old_plane, face.plane_eqn)) {
+ HMOVE(old_plane, face.plane_eqn);
+ ADD_PT(face, ARS_PT(1, 0));
+ ADD_PT(face, ARS_PT(0, 0));
+ ADD_PT(face, ARS_PT(1, 1));
+
+ bu_vls_sprintf(&tmpstr, "%zu%zu", i, j);
+ snprintf(face.label, sizeof(face.label), "%s",
bu_vls_addr(&tmpstr));
+
+ analyze_poly_face(gedp, &face, &table.rows[nfaces]);
+ tot_area += face.area;
+
+ VSCALE(tmp, face.plane_eqn, face.area);
+ tot_vol += fabs(VDOT(face.pts[0], tmp));
+
+ face.npts = 0;
+ nfaces++;
+ }
+ }
+ }
+ tot_vol /= 3.0;
+ table.nrows = nfaces;
+
+ print_faces_table(gedp, &table);
+ print_volume_table(gedp,
+ tot_vol
+ * gedp->ged_wdbp->dbip->dbi_base2local
+ * gedp->ged_wdbp->dbip->dbi_base2local
+ * gedp->ged_wdbp->dbip->dbi_base2local,
+ tot_area
+ * gedp->ged_wdbp->dbip->dbi_base2local
+ * gedp->ged_wdbp->dbip->dbi_base2local,
+ tot_vol/GALLONS_TO_MM3
+ );
+
+ bu_free((char *)face.pts, "analyze_ars: pts");
+ bu_free((char *)table.rows, "analyze_ars: rows");
+ bu_vls_free(&tmpstr);
+}
+
+
+
+// Local Variables:
+// tab-width: 8
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: t
+// c-file-style: "stroustrup"
+// End:
+// ex: shiftwidth=4 tabstop=8
Property changes on: brlcad/branches/analyze_cmd/src/libged/analyze/ars.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: brlcad/branches/analyze_cmd/src/libged/analyze/ged_analyze.h
===================================================================
--- brlcad/branches/analyze_cmd/src/libged/analyze/ged_analyze.h
2020-08-19 15:26:00 UTC (rev 76850)
+++ brlcad/branches/analyze_cmd/src/libged/analyze/ged_analyze.h
2020-08-19 17:50:31 UTC (rev 76851)
@@ -28,11 +28,55 @@
#include "common.h"
+#include "vmath.h"
#include "./ged/defines.h"
__BEGIN_DECLS
+/* Conversion factor for Gallons to cubic millimeters */
+#define GALLONS_TO_MM3 3785411.784
+#define NOT_A_PLANE -1
+
+#define FBUFSIZ 100
+#define NFIELDS 9
+
+typedef struct row_field
+{
+ int nchars;
+ char buf[FBUFSIZ];
+} field_t;
+
+typedef struct table_row
+{
+ int nfields;
+ field_t fields[NFIELDS];
+} row_t;
+
+typedef struct table
+{
+ int nrows;
+ row_t *rows;
+} table_t;
+
+#define ADD_PT(face, pt) do { VMOVE((face).pts[(face).npts], (pt));
(face).npts++; } while (0)
+
+/* contains information used to analyze a polygonal face */
+struct poly_face
+{
+ char label[5];
+ size_t npts;
+ point_t *pts;
+ plane_t plane_eqn;
+ fastf_t area;
+};
+
GED_EXPORT extern void
+print_edges_table(struct ged *gedp, table_t *table);
+
+GED_EXPORT extern void
+print_faces_table(struct ged *gedp, table_t *table);
+
+GED_EXPORT extern void
print_volume_table(
struct ged *gedp,
const fastf_t tot_vol,
@@ -40,7 +84,33 @@
const fastf_t tot_gallons
);
+#define POLY_FACE_INIT_ZERO { { 0, 0, 0, 0, 0 }, 0, NULL, HINIT_ZERO, 0.0 }
+GED_EXPORT extern void
+analyze_poly_face(struct ged *gedp, struct poly_face *face, row_t *row);
+
+GED_EXPORT extern void
+print_faces_table(struct ged *gedp, table_t *table);
+
+
+GED_EXPORT extern void
+analyze_arb8(struct ged *gedp, const struct rt_db_internal *ip);
+
+GED_EXPORT extern void
+analyze_arbn(struct ged *gedp, const struct rt_db_internal *ip);
+
+GED_EXPORT extern void
+analyze_ars(struct ged *gedp, const struct rt_db_internal *ip);
+
+GED_EXPORT extern void
+analyze_superell(struct ged *gedp, const struct rt_db_internal *ip);
+
+GED_EXPORT extern void
+analyze_sketch(struct ged *gedp, const struct rt_db_internal *ip);
+
+GED_EXPORT extern void
+analyze_general(struct ged *gedp, const struct rt_db_internal *ip);
+
__END_DECLS
#endif /* LIBGED_ANALYZE_GED_PRIVATE_H */
Added: brlcad/branches/analyze_cmd/src/libged/analyze/sketch.cpp
===================================================================
--- brlcad/branches/analyze_cmd/src/libged/analyze/sketch.cpp
(rev 0)
+++ brlcad/branches/analyze_cmd/src/libged/analyze/sketch.cpp 2020-08-19
17:50:31 UTC (rev 76851)
@@ -0,0 +1,68 @@
+/* A R S . C P P
+ * BRL-CAD
+ *
+ * Copyright (c) 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 ars.cpp
+ *
+ * Brief description
+ *
+ */
+
+#include "common.h"
+
+#include "vmath.h"
+
+#include "rt/geom.h"
+#include "ged/defines.h"
+#include "../ged_private.h"
+#include "./ged_analyze.h"
+
+void
+analyze_sketch(struct ged *gedp, const struct rt_db_internal *ip)
+{
+ fastf_t area = -1;
+ point_t centroid;
+
+ if (OBJ[ID_SKETCH].ft_surf_area)
+ OBJ[ID_SKETCH].ft_surf_area(&area, ip);
+
+ if (area > 0.0) {
+ bu_vls_printf(gedp->ged_result_str, "\nTotal Area: %10.8f",
+ area
+ * gedp->ged_wdbp->dbip->dbi_local2base
+ * gedp->ged_wdbp->dbip->dbi_local2base
+ );
+ }
+
+ if (OBJ[ID_SKETCH].ft_centroid) {
+ OBJ[ID_SKETCH].ft_centroid(¢roid, ip);
+ bu_vls_printf(gedp->ged_result_str, "\n Centroid: (%g, %g, %g)\n",
+ centroid[X] * gedp->ged_wdbp->dbip->dbi_base2local,
+ centroid[Y] * gedp->ged_wdbp->dbip->dbi_base2local,
+ centroid[Z] * gedp->ged_wdbp->dbip->dbi_base2local);
+ }
+}
+
+// Local Variables:
+// tab-width: 8
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: t
+// c-file-style: "stroustrup"
+// End:
+// ex: shiftwidth=4 tabstop=8
Property changes on: brlcad/branches/analyze_cmd/src/libged/analyze/sketch.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: brlcad/branches/analyze_cmd/src/libged/analyze/superell.cpp
===================================================================
--- brlcad/branches/analyze_cmd/src/libged/analyze/superell.cpp
(rev 0)
+++ brlcad/branches/analyze_cmd/src/libged/analyze/superell.cpp 2020-08-19
17:50:31 UTC (rev 76851)
@@ -0,0 +1,139 @@
+/* S U P E R E L L . C P P
+ * BRL-CAD
+ *
+ * Copyright (c) 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 superell.cpp
+ *
+ * Brief description
+ *
+ */
+
+#include "common.h"
+
+#include "vmath.h"
+
+#include "rt/geom.h"
+#include "ged/defines.h"
+#include "../ged_private.h"
+#include "./ged_analyze.h"
+
+#define PROLATE 1
+#define OBLATE 2
+
+void
+analyze_superell(struct ged *gedp, const struct rt_db_internal *ip)
+{
+ struct rt_superell_internal *superell = (struct rt_superell_internal
*)ip->idb_ptr;
+ fastf_t ma, mb, mc;
+ fastf_t ecc, major_mag, minor_mag;
+ fastf_t vol, sur_area;
+ int type;
+
+ RT_SUPERELL_CK_MAGIC(superell);
+
+ ma = MAGNITUDE(superell->a);
+ mb = MAGNITUDE(superell->b);
+ mc = MAGNITUDE(superell->c);
+
+ type = 0;
+
+ vol = 4.0 * M_PI * ma * mb * mc / 3.0;
+
+ if (fabs(ma-mb) < .00001 && fabs(mb-mc) < .00001) {
+ /* have a sphere */
+ sur_area = 4.0 * M_PI * ma * ma;
+ goto print_results;
+ }
+ if (fabs(ma-mb) < .00001) {
+ /* A == B */
+ if (mc > ma) {
+ /* oblate spheroid */
+ type = OBLATE;
+ major_mag = mc;
+ minor_mag = ma;
+ } else {
+ /* prolate spheroid */
+ type = PROLATE;
+ major_mag = ma;
+ minor_mag = mc;
+ }
+ } else
+ if (fabs(ma-mc) < .00001) {
+ /* A == C */
+ if (mb > ma) {
+ /* oblate spheroid */
+ type = OBLATE;
+ major_mag = mb;
+ minor_mag = ma;
+ } else {
+ /* prolate spheroid */
+ type = PROLATE;
+ major_mag = ma;
+ minor_mag = mb;
+ }
+ } else
+ if (fabs(mb-mc) < .00001) {
+ /* B == C */
+ if (ma > mb) {
+ /* oblate spheroid */
+ type = OBLATE;
+ major_mag = ma;
+ minor_mag = mb;
+ } else {
+ /* prolate spheroid */
+ type = PROLATE;
+ major_mag = mb;
+ minor_mag = ma;
+ }
+ } else {
+ bu_vls_printf(gedp->ged_result_str, " Cannot find surface
area\n");
+ return;
+ }
+ ecc = sqrt(major_mag*major_mag - minor_mag*minor_mag) / major_mag;
+ if (type == PROLATE) {
+ sur_area = M_2PI * minor_mag * minor_mag +
+ (M_2PI * (major_mag*minor_mag/ecc) * asin(ecc));
+ } else {
+ /* type == OBLATE */
+ sur_area = M_2PI * major_mag * major_mag +
+ (M_PI * (minor_mag*minor_mag/ecc) * log((1.0+ecc)/(1.0-ecc)));
+ }
+
+print_results:
+ print_volume_table(gedp,
+ vol
+ * gedp->ged_wdbp->dbip->dbi_base2local
+ * gedp->ged_wdbp->dbip->dbi_base2local
+ * gedp->ged_wdbp->dbip->dbi_base2local,
+ sur_area
+ * gedp->ged_wdbp->dbip->dbi_base2local
+ * gedp->ged_wdbp->dbip->dbi_base2local,
+ vol/GALLONS_TO_MM3
+ );
+}
+
+
+
+// Local Variables:
+// tab-width: 8
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: t
+// c-file-style: "stroustrup"
+// End:
+// ex: shiftwidth=4 tabstop=8
Property changes on: brlcad/branches/analyze_cmd/src/libged/analyze/superell.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: brlcad/branches/analyze_cmd/src/libged/analyze/util.cpp
===================================================================
--- brlcad/branches/analyze_cmd/src/libged/analyze/util.cpp 2020-08-19
15:26:00 UTC (rev 76850)
+++ brlcad/branches/analyze_cmd/src/libged/analyze/util.cpp 2020-08-19
17:50:31 UTC (rev 76851)
@@ -6,6 +6,7 @@
#include <string.h>
}
+#include <cassert>
#include <limits>
extern "C" {
@@ -15,27 +16,6 @@
#include "./ged_analyze.h"
}
-#define FBUFSIZ 100
-#define NFIELDS 9
-
-typedef struct row_field
-{
- int nchars;
- char buf[FBUFSIZ];
-} field_t;
-
-typedef struct table_row
-{
- int nfields;
- field_t fields[NFIELDS];
-} row_t;
-
-typedef struct table
-{
- int nrows;
- row_t *rows;
-} table_t;
-
void get_dashes(field_t *f, const int ndashes)
{
int i;
@@ -47,6 +27,406 @@
}
void
+print_edges_table(struct ged *gedp, table_t *table)
+{
+
+/* table header
+
+
+--------------------+--------------------+--------------------+--------------------+
+ | EDGE LEN | EDGE LEN | EDGE LEN | EDGE
LEN |
+
+--------------------+--------------------+--------------------+--------------------+
+
+*/
+
+ int i;
+ int tcol, nd, nrow, nrows;
+ int maxwidth[] = {0, 0, 0,
+ 0, 0, 0,
+ 0, 0};
+ int indent = 2;
+ field_t dashes;
+ char EDGE[] = {"EDGE"};
+ int elen = strlen(EDGE);
+ char LEN[] = {"LENGTH"};
+ int llen = strlen(LEN);
+ char buf[FBUFSIZ];
+
+ /* put four edges per row making 8 columns */
+ /* this table has 8 columns per row: 2 columns per edge; 4 edges per row */
+
+ /* collect max table column widths */
+ tcol = 0;
+ for (i = 0; i < table->nrows; ++i) {
+ /* field 0 */
+ int field = 0;
+ if (maxwidth[tcol] < table->rows[i].fields[field].nchars)
+ maxwidth[tcol] = table->rows[i].fields[field].nchars;
+ if (maxwidth[tcol] < elen)
+ maxwidth[tcol] = elen;
+
+ /* field 1 */
+ field = 1;
+ if (maxwidth[tcol+1] < table->rows[i].fields[field].nchars)
+ maxwidth[tcol+1] = table->rows[i].fields[field].nchars;
+ if (maxwidth[tcol] < llen)
+ maxwidth[tcol] = llen;
+
+ /* iterate on columns */
+ tcol += 2;
+ tcol = tcol > 6 ? 0 : tcol;
+ }
+
+ /* header row 1 */
+ /* print dashes in 4 sets */
+ nd = maxwidth[0] + maxwidth[1] + 3; /* 1 space between numbers and one at
each end */
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "%-*.*s+%-*.*s",
+ indent, indent, " ",
+ nd, nd, dashes.buf);
+ nd = maxwidth[2] + maxwidth[3] + 3; /* 1 space between numbers and one at
each end */
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "+%-*.*s",
+ nd, nd, dashes.buf);
+ nd = maxwidth[4] + maxwidth[5] + 3; /* 1 space between numbers and one at
each end */
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "+%-*.*s",
+ nd, nd, dashes.buf);
+ nd = maxwidth[6] + maxwidth[7] + 3; /* 1 space between numbers and one at
each end */
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "+%-*.*s+\n",
+ nd, nd, dashes.buf);
+
+ /* header row 2 */
+ /* print titles in 4 sets */
+
+ /* bu_vls_printf can't handle this at the moment */
+ bu_vls_printf(gedp->ged_result_str, "%-*.*s| %-*.*s %*.*s ",
+ indent, indent, " ",
+ maxwidth[0], maxwidth[0], EDGE,
+ maxwidth[1], maxwidth[1], LEN);
+ bu_vls_printf(gedp->ged_result_str, "| %-*.*s %*.*s ",
+ maxwidth[2], maxwidth[2], EDGE,
+ maxwidth[3], maxwidth[3], LEN);
+ bu_vls_printf(gedp->ged_result_str, "| %-*.*s %*.*s ",
+ maxwidth[4], maxwidth[4], EDGE,
+ maxwidth[5], maxwidth[5], LEN);
+ bu_vls_printf(gedp->ged_result_str, "| %-*.*s %*.*s |\n",
+ maxwidth[6], maxwidth[6], EDGE,
+ maxwidth[7], maxwidth[7], LEN);
+
+ /* header row 3 */
+ /* print dashes in 4 sets */
+ nd = maxwidth[0] + maxwidth[1] + 3; /* 1 space between numbers and one at
each end */
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "%-*.*s+%-*.*s",
+ indent, indent, " ",
+ nd, nd, dashes.buf);
+ nd = maxwidth[2] + maxwidth[3] + 3; /* 1 space between numbers and one at
each end */
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "+%-*.*s",
+ nd, nd, dashes.buf);
+ nd = maxwidth[4] + maxwidth[5] + 3; /* 1 space between numbers and one at
each end */
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "+%-*.*s",
+ nd, nd, dashes.buf);
+ nd = maxwidth[6] + maxwidth[7] + 3; /* 1 space between numbers and one at
each end */
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "+%-*.*s+\n",
+ nd, nd, dashes.buf);
+
+ /* print the data lines */
+ /* collect max table column widths */
+ tcol = 0;
+ nrow = 0;
+ for (i = 0; i < table->nrows; ++i) {
+ int field;
+
+ if (tcol == 0) {
+ /* need to start a row */
+ snprintf(buf, FBUFSIZ, "%-*.*s|",
+ indent, indent, " ");
+ bu_vls_printf(gedp->ged_result_str, "%s", buf);
+ }
+
+ /* data in sets of two */
+ /* field 0 */
+ field = 0;
+ /* FIXME: using snprintf because bu_vls_printf is broken for complex
formats */
+ snprintf(buf, FBUFSIZ, " %-*.*s",
+ maxwidth[tcol], maxwidth[tcol],
table->rows[i].fields[field].buf);
+ bu_vls_printf(gedp->ged_result_str, "%s", buf);
+
+ /* field 1 */
+ field = 1;
+ /* FIXME: using snprintf because bu_vls_printf is broken for complex
formats */
+ snprintf(buf, FBUFSIZ, " %-*.*s |",
+ maxwidth[tcol+1], maxwidth[tcol+1],
table->rows[i].fields[field].buf);
+ bu_vls_printf(gedp->ged_result_str, "%s", buf);
+
+ /* iterate on columns */
+ tcol += 2;
+
+ if (tcol > 6) {
+ /* time for a newline to end the row */
+ bu_vls_printf(gedp->ged_result_str, "\n");
+ tcol = 0;
+ ++nrow;
+ }
+ }
+
+ /* we may have a row to finish */
+ nrows = table->nrows % 4;
+ if (nrows) {
+ assert(tcol < 8);
+
+ /* write blanks */
+ while (tcol < 7) {
+
+ /* data in sets of two */
+ /* this is field 0 */
+ /* FIXME: using snprintf because bu_vls_printf is broken for
complex formats */
+ snprintf(buf, FBUFSIZ, " %-*.*s",
+ maxwidth[tcol], maxwidth[tcol], " ");
+ bu_vls_printf(gedp->ged_result_str, "%s", buf);
+
+ /* this is field 1 */
+ /* FIXME: using snprintf because bu_vls_printf is broken for
complex formats */
+ snprintf(buf, FBUFSIZ, " %-*.*s |",
+ maxwidth[tcol+1], maxwidth[tcol+1], " ");
+ bu_vls_printf(gedp->ged_result_str, "%s", buf);
+
+ /* iterate on columns */
+ tcol += 2;
+
+ if (tcol > 6) {
+ /* time for a newline to end the row */
+ bu_vls_printf(gedp->ged_result_str, "\n");
+ }
+ }
+ }
+
+ /* close the table */
+ /* print dashes in 4 sets */
+ nd = maxwidth[0] + maxwidth[1] + 3; /* 1 space between numbers and one at
each end */
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "%-*.*s+%-*.*s",
+ indent, indent, " ",
+ nd, nd, dashes.buf);
+ nd = maxwidth[2] + maxwidth[3] + 3; /* 1 space between numbers and one at
each end */
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "+%-*.*s",
+ nd, nd, dashes.buf);
+ nd = maxwidth[4] + maxwidth[5] + 3; /* 1 space between numbers and one at
each end */
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "+%-*.*s",
+ nd, nd, dashes.buf);
+ nd = maxwidth[6] + maxwidth[7] + 3; /* 1 space between numbers and one at
each end */
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "+%-*.*s+\n",
+ nd, nd, dashes.buf);
+}
+
+
+void
+print_faces_table(struct ged *gedp, table_t *table)
+{
+
+/* table header
+
+
+------+-----------------------------+--------------------------------------------------+-----------------+
+ | FACE | ROT FB | PLANE EQUATION
| SURFACE AREA |
+
+------+-----------------------------+--------------------------------------------------+-----------------+
+
+*/
+
+ /* track actual table column widths */
+ /* this table has 8 columns */
+ int maxwidth[8] = {0, 0, 0,
+ 0, 0, 0,
+ 0, 0};
+ int i, j;
+ int c0, h1a, h1b, h1c;
+ int h2a, h2b, h2c;
+ int c2, c2a, c2b, c2c;
+ int f7, f7a, f7b, f7c;
+ int nd, tnd;
+ field_t dashes;
+ char ROT[] = {"ROT"};
+ char FB[] = {"FB"};
+ char PA[] = {"PLANE EQUATION"};
+ char SA[] = {"SURFACE AREA"};
+
+ /* get max fields widths */
+ for (i = 0; i < table->nrows; ++i) {
+ for (j = 0; j < table->rows[i].nfields; ++j) {
+ if (table->rows[i].fields[j].nchars > maxwidth[j])
+ maxwidth[j] = table->rows[i].fields[j].nchars;
+ }
+ }
+
+ /* blank line following previous table */
+ bu_vls_printf(gedp->ged_result_str, "\n");
+
+ /* get max width of header columns (not counting single space on either
side) */
+ c0 = maxwidth[0] > 4 ? maxwidth[0] : 4;
+
+ /* print "ROT" in center of field 1 space */
+ h1b = strlen(ROT);
+ h1a = (maxwidth[1] - h1b)/2;
+ h1c = (maxwidth[1] - h1b - h1a);
+
+ /* print "FB" in center of field 2 space */
+ h2b = strlen(FB);
+ h2a = (maxwidth[2] - h2b)/2;
+ h2c = (maxwidth[2] - h2b - h2a);
+
+ /* get width of subcolumns of header column 2 */
+ /* print "PLANE EQUATION" in center of columns 2 space */
+ c2 = maxwidth[3] + maxwidth[4] + maxwidth[5] + maxwidth[6] + 3; /* 3
spaces between fields */
+ c2b = strlen(PA);
+ c2a = (c2 - c2b)/2;
+ c2c = (c2 - c2b - c2a);
+
+ /* print "SURFACE AREA" in center of field 7 space */
+ f7b = strlen(SA);
+ f7 = maxwidth[7] > f7b ? maxwidth[7] : f7b;
+ f7a = (f7 - f7b)/2;
+ f7c = (f7 - f7b - f7a);
+
+ /* print the pieces */
+
+ /* header row 1 */
+ bu_vls_printf(gedp->ged_result_str, "+-");
+ nd = c0; tnd = nd;
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "%-*.*s",
+ nd, nd, dashes.buf);
+ bu_vls_printf(gedp->ged_result_str, "-+-");
+ nd = h1a + h1b + h1c + 1 + h2a + h2b + h2c; tnd += nd + 3;
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "%*.*s",
+ nd, nd, dashes.buf);
+ bu_vls_printf(gedp->ged_result_str, "-+-");
+ nd = c2a + c2b + c2c; tnd += nd + 3;
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "%*.*s",
+ nd, nd, dashes.buf);
+ bu_vls_printf(gedp->ged_result_str, "-+-");
+ nd = f7a + f7b + f7c; tnd += nd + 3;
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "%*.*s",
+ nd, nd, dashes.buf);
+ bu_vls_printf(gedp->ged_result_str, "-+\n");
+
+ /* header row 2 */
+ bu_vls_printf(gedp->ged_result_str, "| ");
+
+ bu_vls_printf(gedp->ged_result_str, "%-*.*s", c0, c0, "FACE");
+
+ bu_vls_printf(gedp->ged_result_str, " | ");
+
+
+ bu_vls_printf(gedp->ged_result_str, "%*.*s", h1a, h1a, " ");
+
+ bu_vls_printf(gedp->ged_result_str, "%*.*s", h1b, h1b, ROT);
+
+ bu_vls_printf(gedp->ged_result_str, "%*.*s", h1c+h2a, h1c+h2a, " ");
+
+ bu_vls_printf(gedp->ged_result_str, "%*.*s", h2b, h2b, FB);
+
+ bu_vls_printf(gedp->ged_result_str, "%*.*s ", h2c, h2c, " ");
+
+
+ bu_vls_printf(gedp->ged_result_str, " | ");
+
+
+ bu_vls_printf(gedp->ged_result_str, "%*.*s", c2a, c2a, " ");
+
+ bu_vls_printf(gedp->ged_result_str, "%*.*s", c2b, c2b, PA);
+
+ bu_vls_printf(gedp->ged_result_str, "%*.*s", c2c, c2c, " ");
+
+
+ bu_vls_printf(gedp->ged_result_str, " | ");
+
+ bu_vls_printf(gedp->ged_result_str, "%*.*s", f7a, f7a, " ");
+
+ bu_vls_printf(gedp->ged_result_str, "%*.*s", f7b, f7b, SA);
+
+ bu_vls_printf(gedp->ged_result_str, "%*.*s", f7c, f7c, " ");
+
+ bu_vls_printf(gedp->ged_result_str, " |\n");
+
+ /* header row 3 */
+ bu_vls_printf(gedp->ged_result_str, "+-");
+ nd = c0; tnd = nd;
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "%-*.*s",
+ nd, nd, dashes.buf);
+ bu_vls_printf(gedp->ged_result_str, "-+-");
+ nd = h1a + h1b + h1c + 1 + h2a + h2b + h2c; tnd += nd + 3;
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "%*.*s",
+ nd, nd, dashes.buf);
+ bu_vls_printf(gedp->ged_result_str, "-+-");
+ nd = c2a + c2b + c2c; tnd += nd + 3;
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "%*.*s",
+ nd, nd, dashes.buf);
+ bu_vls_printf(gedp->ged_result_str, "-+-");
+ nd = f7a + f7b + f7c; tnd += nd + 3;
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "%*.*s",
+ nd, nd, dashes.buf);
+ bu_vls_printf(gedp->ged_result_str, "-+\n");
+
+ /* output table data rows */
+ for (i = 0; i < table->nrows; ++i) {
+ /* may not have a row with data */
+ if (table->rows[i].nfields == 0)
+ continue;
+ if (table->rows[i].nfields == NOT_A_PLANE)
+ bu_vls_printf(gedp->ged_result_str, "***NOT A PLANE ***");
+
+ bu_vls_printf(gedp->ged_result_str, "|");
+ for (j = 0; j < table->rows[i].nfields; ++j) {
+ assert(table->rows[i].fields[j].buf);
+ bu_vls_printf(gedp->ged_result_str, " %*.*s",
+ maxwidth[j], maxwidth[j],
+ table->rows[i].fields[j].buf);
+ /* do we need a separator? */
+ if (j == 0 || j == 2 || j == 6 || j == 7)
+ bu_vls_printf(gedp->ged_result_str, " |");
+ }
+ /* close the row */
+ bu_vls_printf(gedp->ged_result_str, "\n");
+ }
+
+ /* close the table with the ender row */
+ bu_vls_printf(gedp->ged_result_str, "+-");
+ nd = c0; tnd = nd;
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "%-*.*s",
+ nd, nd, dashes.buf);
+ bu_vls_printf(gedp->ged_result_str, "-+-");
+ nd = h1a + h1b + h1c + 1 + h2a + h2b + h2c; tnd += nd + 3;
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "%*.*s",
+ nd, nd, dashes.buf);
+ bu_vls_printf(gedp->ged_result_str, "-+-");
+ nd = c2a + c2b + c2c; tnd += nd + 3;
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "%*.*s",
+ nd, nd, dashes.buf);
+ bu_vls_printf(gedp->ged_result_str, "-+-");
+ nd = f7a + f7b + f7c; tnd += nd + 3;
+ get_dashes(&dashes, nd);
+ bu_vls_printf(gedp->ged_result_str, "%*.*s",
+ nd, nd, dashes.buf);
+ bu_vls_printf(gedp->ged_result_str, "-+\n");
+}
+
+void
print_volume_table(
struct ged *gedp,
const fastf_t tot_vol,
@@ -136,7 +516,146 @@
}
+/**
+ * finds direction cosines and rotation, fallback angles of a unit vector
+ * angles = pointer to 5 fastf_t's to store angles
+ * unitv = pointer to the unit vector (previously computed)
+ */
+static void
+findang(fastf_t *angles, fastf_t *unitv)
+{
+ int i;
+ fastf_t f;
+ /* convert direction cosines into axis angles */
+ for (i = X; i <= Z; i++) {
+ if (unitv[i] <= -1.0)
+ angles[i] = -90.0;
+ else if (unitv[i] >= 1.0)
+ angles[i] = 90.0;
+ else
+ angles[i] = acos(unitv[i]) * RAD2DEG;
+ }
+
+ /* fallback angle */
+ if (unitv[Z] <= -1.0)
+ unitv[Z] = -1.0;
+ else if (unitv[Z] >= 1.0)
+ unitv[Z] = 1.0;
+ angles[4] = asin(unitv[Z]);
+
+ /* rotation angle */
+ /* For the tolerance below, on an SGI 4D/70, cos(asin(1.0)) != 0.0
+ * with an epsilon of +/- 1.0e-17, so the tolerance below was
+ * substituted for the original +/- 1.0e-20.
+ */
+ if ((f = cos(angles[4])) > 1.0e-16 || f < -1.0e-16) {
+ f = unitv[X]/f;
+ if (f <= -1.0)
+ angles[3] = 180.0;
+ else if (f >= 1.0)
+ angles[3] = 0.0;
+ else
+ angles[3] = RAD2DEG * acos(f);
+ } else
+ angles[3] = 0.0;
+
+ if (unitv[Y] < 0)
+ angles[3] = 360.0 - angles[3];
+
+ angles[4] *= RAD2DEG;
+}
+
+
+
+/**
+ * general analyze function for polygonal faces.
+ * Currently used for:
+ * - arb8
+ * - arbn
+ * - ars
+ *
+ * returns:
+ * - area in face->area
+ * - print_faces_table() information in row
+ * - sorts vertices in face->pts into ccw order
+ */
+void
+analyze_poly_face(struct ged *gedp, struct poly_face *face, row_t *row)
+{
+ fastf_t angles[5];
+
+ findang(angles, face->plane_eqn);
+
+ /* sort points */
+ bg_3d_polygon_sort_ccw(face->npts, face->pts, face->plane_eqn);
+ bg_3d_polygon_area(&face->area, face->npts, (const point_t *)face->pts);
+
+ /* store face information for pretty printing */
+ row->nfields = 8;
+ row->fields[0].nchars = sprintf(row->fields[0].buf, "%4s", face->label);
+ row->fields[1].nchars = sprintf(row->fields[1].buf, "%10.8f", angles[3]);
+ row->fields[2].nchars = sprintf(row->fields[2].buf, "%10.8f", angles[4]);
+ row->fields[3].nchars = sprintf(row->fields[3].buf, "%10.8f",
face->plane_eqn[X]);
+ row->fields[4].nchars = sprintf(row->fields[4].buf, "%10.8f",
face->plane_eqn[Y]);
+ row->fields[5].nchars = sprintf(row->fields[5].buf, "%10.8f",
face->plane_eqn[Z]);
+ row->fields[6].nchars = sprintf(row->fields[6].buf, "%10.8f",
+
face->plane_eqn[W]*gedp->ged_wdbp->dbip->dbi_base2local);
+ row->fields[7].nchars = sprintf(row->fields[7].buf, "%10.8f",
+
face->area*gedp->ged_wdbp->dbip->dbi_base2local*gedp->ged_wdbp->dbip->dbi_base2local);
+}
+
+/**
+ * general analyze function for primitives that can be analyzed using volume
+ * and surface area functions from the rt_functab.
+ * Currently used for:
+ * - ell
+ * - tor
+ * - tgc
+ * - rpc
+ * - eto
+ * - epa
+ * - part
+ * - rhc
+ */
+void
+analyze_general(struct ged *gedp, const struct rt_db_internal *ip)
+{
+ fastf_t vol, area;
+ point_t centroid;
+
+ vol = area = -1.0;
+
+ if (OBJ[ip->idb_minor_type].ft_volume) {
+ OBJ[ip->idb_minor_type].ft_volume(&vol, ip);
+ }
+ if (OBJ[ip->idb_minor_type].ft_surf_area) {
+ OBJ[ip->idb_minor_type].ft_surf_area(&area, ip);
+ }
+
+ if (OBJ[ip->idb_minor_type].ft_centroid) {
+ OBJ[ip->idb_minor_type].ft_centroid(¢roid, ip);
+ bu_vls_printf(gedp->ged_result_str, "\n Centroid: (%g, %g, %g)\n",
+ centroid[X] * gedp->ged_wdbp->dbip->dbi_base2local,
+ centroid[Y] * gedp->ged_wdbp->dbip->dbi_base2local,
+ centroid[Z] * gedp->ged_wdbp->dbip->dbi_base2local);
+ }
+
+ print_volume_table(gedp,
+ vol
+ * gedp->ged_wdbp->dbip->dbi_base2local
+ * gedp->ged_wdbp->dbip->dbi_base2local
+ * gedp->ged_wdbp->dbip->dbi_base2local,
+ area
+ * gedp->ged_wdbp->dbip->dbi_base2local
+ * gedp->ged_wdbp->dbip->dbi_base2local,
+ vol/GALLONS_TO_MM3
+ );
+}
+
+
+
+
// Local Variables:
// tab-width: 8
// mode: C++
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