Revision: 77303
http://sourceforge.net/p/brlcad/code/77303
Author: starseeker
Date: 2020-10-01 13:15:27 +0000 (Thu, 01 Oct 2020)
Log Message:
-----------
Merge from trunk - r77220 through r77302
Modified Paths:
--------------
brlcad/branches/bioh/NEWS
brlcad/branches/bioh/TODO
brlcad/branches/bioh/bench/pixcmp.c
brlcad/branches/bioh/bench/run.sh
brlcad/branches/bioh/doc/docbook/CMakeLists.txt
brlcad/branches/bioh/doc/docbook/system/mann/analyze.xml
brlcad/branches/bioh/doc/docbook/system/mann/kill.xml
brlcad/branches/bioh/doc/legal/embedded/SPSR.txt
brlcad/branches/bioh/doc/legal/other/CMakeLists.txt
brlcad/branches/bioh/include/ged/commands.h
brlcad/branches/bioh/src/conv/fast4-g.c
brlcad/branches/bioh/src/libbrep/CMakeLists.txt
brlcad/branches/bioh/src/libbrep/boolean.cpp
brlcad/branches/bioh/src/libbrep/intersect.cpp
brlcad/branches/bioh/src/libbrep/tests/CMakeLists.txt
brlcad/branches/bioh/src/libged/analyze/CMakeLists.txt
brlcad/branches/bioh/src/libged/brep/CMakeLists.txt
brlcad/branches/bioh/src/libged/brep/brep.cpp
brlcad/branches/bioh/src/libged/brep/ged_brep.h
brlcad/branches/bioh/src/libged/exec_mapping.cpp
brlcad/branches/bioh/src/libged/kill/kill.c
brlcad/branches/bioh/src/libged/pnts_util.c
brlcad/branches/bioh/src/libged/pnts_util.h
brlcad/branches/bioh/src/libged/tests/CMakeLists.txt
brlcad/branches/bioh/src/libtclcad/commands.c
brlcad/branches/bioh/src/other/libspsr/Src/PointStream.h
brlcad/branches/bioh/src/other/libspsr/Src/PointStream.inl
brlcad/branches/bioh/src/other/libspsr/Src/PoissonRecon.cpp
brlcad/branches/bioh/src/other/libspsr/Src/SPSR.cpp
brlcad/branches/bioh/src/other/libspsr/Src/SurfaceTrimmer.cpp
brlcad/branches/bioh/src/other/libspsr.dist
brlcad/branches/bioh/src/tclscripts/lib/Ged.tcl
Added Paths:
-----------
brlcad/branches/bioh/doc/docbook/devguides/
brlcad/branches/bioh/src/libbrep/brep_defines.h
brlcad/branches/bioh/src/libbrep/debug_plot.cpp
brlcad/branches/bioh/src/libbrep/debug_plot.h
brlcad/branches/bioh/src/libbrep/tests/ppx.cpp
brlcad/branches/bioh/src/libged/analyze/analyze.cpp
brlcad/branches/bioh/src/libged/analyze/arb8.cpp
brlcad/branches/bioh/src/libged/analyze/arbn.cpp
brlcad/branches/bioh/src/libged/analyze/ars.cpp
brlcad/branches/bioh/src/libged/analyze/ged_analyze.h
brlcad/branches/bioh/src/libged/analyze/op_pnts_vol.cpp
brlcad/branches/bioh/src/libged/analyze/sketch.cpp
brlcad/branches/bioh/src/libged/analyze/superell.cpp
brlcad/branches/bioh/src/libged/analyze/util.cpp
brlcad/branches/bioh/src/libged/brep/dplot.c
brlcad/branches/bioh/src/libged/brep/dplot_parser.lemon
brlcad/branches/bioh/src/libged/brep/dplot_reader.c
brlcad/branches/bioh/src/libged/brep/dplot_reader.h
brlcad/branches/bioh/src/libged/brep/dplot_scanner.perplex
brlcad/branches/bioh/src/libged/tests/pnts_in_out.g
brlcad/branches/bioh/src/other/libspsr/Src/PlyVertexMini.h
Removed Paths:
-------------
brlcad/branches/bioh/doc/legal/other/SPSR.txt
brlcad/branches/bioh/src/libged/analyze/analyze.c
brlcad/branches/bioh/src/other/libspsr/Src/Ply.h
brlcad/branches/bioh/src/other/libspsr/Src/PlyFile.cpp
Property Changed:
----------------
brlcad/branches/bioh/
brlcad/branches/bioh/NEWS
brlcad/branches/bioh/bench/
brlcad/branches/bioh/doc/
brlcad/branches/bioh/include/
brlcad/branches/bioh/src/libged/kill/kill.c
brlcad/branches/bioh/src/other/
brlcad/branches/bioh/src/other/libspsr/
Index: brlcad/branches/bioh
===================================================================
--- brlcad/branches/bioh 2020-10-01 13:13:00 UTC (rev 77302)
+++ brlcad/branches/bioh 2020-10-01 13:15:27 UTC (rev 77303)
Property changes on: brlcad/branches/bioh
___________________________________________________________________
Modified: svn:mergeinfo
## -1,5 +1,6 ##
/brlcad/branches/RELEASE:57439,57447-57860,69901-69913,70323-70333,71915-72242,72525-72534,72826-72858,74376-74454,74964-75140,75372-75685,76001-76451,76693-76768,77107-77132,77145-77155
-/brlcad/branches/brep-debug:61373,61375,61404,61427,61429,61470,61544,61567,61576,61999,62018,62094,62098,62107,62117,62406,62416-62519,62521-62584,62593-62614,62623,62658,62660-62674,62681-62771,62876,62901,62907,62910,62925,62928,62931-63025,63027,63051,63054-63056,63069,63071-63073,63122,63160-63161,63165,63171,63184,63187,63189-63190,63193-63196,63200,63202,63205-63210,63213,63219-63225,63232-63233,63236,63238,63338,63350-63353,63481,63618,63669,64173-64174,64176-64177,64229-64233,64242,64244,64360-64362,65165,65245,65249,65334,65833-65834,66370-66375,66931-66932,66934,67012-67015,67018-67019,67021-67022,67406,67740,67746-67748,67950,67952,68144-68145,68636,68640-68643,68820,69081,69109,69168,69206,69289,69346,69460-69461,69582-69583,69719-69721,69857-69859,69927,69995-69996,70148-70149,70347-70349,70377,70526-70527,71006-71007,71009-71022,71046-71047,71049,71096-71100
+/brlcad/branches/analyze_cmd:76836-77221
+/brlcad/branches/brep-debug:61373,61375,61404,61427,61429,61470,61544,61567,61576,61999,62018,62094,62098,62107,62117,62406,62416-62519,62521-62584,62593-62614,62623,62658,62660-62674,62681-62771,62876,62901,62907,62910,62925,62928,62931-63025,63027,63051,63054-63056,63069,63071-63073,63122,63160-63161,63165,63171,63184,63187,63189-63190,63193-63196,63200,63202,63205-63210,63213,63219-63225,63232-63233,63236,63238,63338,63350-63353,63481,63618,63669,64173-64174,64176-64177,64229-64233,64242,64244,64360-64362,65165,65245,65249,65334,65833-65834,66370-66375,66931-66932,66934,67012-67015,67018-67019,67021-67022,67406,67740,67746-67748,67950,67952,68144-68145,68636,68640-68643,68820,69081,69109,69168,69206,69289,69346,69460-69461,69582-69583,69719-69721,69857-69859,69927,69995-69996,70148-70149,70347-70349,70377,70526-70527,71006-71007,71009-71022,71046-71047,71049,71096-71100,77226-77229
/brlcad/branches/bullet:62518
/brlcad/branches/cmake:43219
/brlcad/branches/dm-fb-merge:75426-76198
## -9,4 +10,4 ##
/brlcad/branches/osg:62110-62113
/brlcad/branches/prep-cache:68236-68933
/brlcad/branches/tcltk86:68300-75257
-/brlcad/trunk:75720-76157,76160-76365,76386-77219
\ No newline at end of property
+/brlcad/trunk:75720-76157,76160-76365,76386-77302
\ No newline at end of property
Modified: brlcad/branches/bioh/NEWS
===================================================================
--- brlcad/branches/bioh/NEWS 2020-10-01 13:13:00 UTC (rev 77302)
+++ brlcad/branches/bioh/NEWS 2020-10-01 13:15:27 UTC (rev 77303)
@@ -13,6 +13,12 @@
--- 2020-xx-xx Release 7.32.2 ---
----------------------------------------------------------------------
+* applied shorter default title in fast4-g conversions - Cliff Yapp
+* improved pixcmp support for subset image comparisons - Sean Morrison
+* added subtract subcommand to MGED analyze command - Cliff Yapp
+* added intersect subcommand to MGED analyze command - Cliff Yapp
+* added summarize subcommand to MGED analyze command - Cliff Yapp
+* added quiet (-q) flag to MGED kill command - Cliff Yapp
* added MGED stat command for reporting of object info - Cliff Yapp
* corrected examples in gdiff man page - Cliff Yapp
* fixed help message for -F option on gdiff command - Cliff Yapp
Property changes on: brlcad/branches/bioh/NEWS
___________________________________________________________________
Modified: svn:mergeinfo
## -8,4 +8,4 ##
/brlcad/branches/osg/NEWS:62110-62113
/brlcad/branches/prep-cache/NEWS:68236-68933
/brlcad/branches/tcltk86/NEWS:68300-75257
-/brlcad/trunk/NEWS:75728-75834,75934-76085,76134-76146,76148-76154,76160-76351,76386-76505,76569-76653,76685-76859,76862-77219
\ No newline at end of property
+/brlcad/trunk/NEWS:75728-75834,75934-76085,76134-76146,76148-76154,76160-76351,76386-76505,76569-76653,76685-76859,76862-77302
\ No newline at end of property
Modified: brlcad/branches/bioh/TODO
===================================================================
--- brlcad/branches/bioh/TODO 2020-10-01 13:13:00 UTC (rev 77302)
+++ brlcad/branches/bioh/TODO 2020-10-01 13:15:27 UTC (rev 77303)
@@ -18,12 +18,9 @@
THESE TASKS SHOULD HAPPEN BEFORE THE NEXT RELEASE
-------------------------------------------------
-* Release Testing, final commit reviews
+* Update libgcv plugin installation location - now that its
+ available, they belong with the other plugins in libexec
-
-THESE TASKS SHOULD HAPPEN WITHIN TWO RELEASE ITERATIONS
--------------------------------------------------------
-
* The following will be removed from MGED's menu bar (unused
features, can be accomplished another way, or will be exposed
only as lower level settings when there are sensible defaults
@@ -169,6 +166,11 @@
allocation, not just do some work
+THESE TASKS SHOULD HAPPEN WITHIN TWO RELEASE ITERATIONS
+-------------------------------------------------------
+
+
+
THESE ARE UNSCHEDULED BACKLOG TASKS
-----------------------------------
Index: brlcad/branches/bioh/bench
===================================================================
--- brlcad/branches/bioh/bench 2020-10-01 13:13:00 UTC (rev 77302)
+++ brlcad/branches/bioh/bench 2020-10-01 13:15:27 UTC (rev 77303)
Property changes on: brlcad/branches/bioh/bench
___________________________________________________________________
Modified: svn:mergeinfo
## -8,4 +8,4 ##
/brlcad/branches/osg/bench:62110-62113
/brlcad/branches/prep-cache/bench:68236-68933
/brlcad/branches/tcltk86/bench:68300-75257
-/brlcad/trunk/bench:75728-75834,75986-76085,76160-76351,76685-76859,77084-77219
\ No newline at end of property
+/brlcad/trunk/bench:75728-75834,75986-76085,76160-76351,76685-76859,77084-77302
\ No newline at end of property
Modified: brlcad/branches/bioh/bench/pixcmp.c
===================================================================
--- brlcad/branches/bioh/bench/pixcmp.c 2020-10-01 13:13:00 UTC (rev 77302)
+++ brlcad/branches/bioh/bench/pixcmp.c 2020-10-01 13:15:27 UTC (rev 77303)
@@ -121,7 +121,8 @@
{
FILE *f1 = NULL;
FILE *f2 = NULL;
- struct stat sf1, sf2;
+ struct stat sf1 = {0};
+ struct stat sf2 = {0};
size_t matching = 0;
size_t off1 = 0;
@@ -190,6 +191,10 @@
}
/* printf("Skip from FILE1: %ld and from FILE2: %ld\n", f1_skip, f2_skip);
*/
+ if (!print_bytes) {
+ f1_skip *= 3;
+ f2_skip *= 3;
+ }
if (BU_STR_EQUAL(argv[0], "-")) {
f1 = stdin;
@@ -204,18 +209,25 @@
exit(FILE_ERROR);
}
- stat(argv[0], &sf1);
- stat(argv[1], &sf2);
+ fstat(fileno(f1), &sf1);
+ fstat(fileno(f2), &sf2);
- if (sf1.st_size != sf2.st_size) {
- bu_exit(FILE_ERROR, "Different file sizes found: %s(%d) and %s(%d).
Cannot perform pixcmp.\n", argv[0], (int)sf1.st_size, argv[1],
(int)sf2.st_size);
+ if ((sf1.st_size - f1_skip) != (sf2.st_size - f2_skip)) {
+ bu_log("WARNING: Different image sizes detected\n");
+ if (print_bytes) {
+ bu_log("\t%s: %7zu bytes (%8zu bytes, skipping %7zu)\n",
+ argv[0], sf1.st_size - f1_skip, sf1.st_size, f1_skip);
+ bu_log("\t%s: %7zu bytes (%8zu bytes, skipping %7zu)\n",
+ argv[1], sf2.st_size - f2_skip, sf2.st_size, f2_skip);
+ } else {
+ bu_log("\t%s: %7zu pixels (%8zu bytes, skipping %7zu)\n",
+ argv[0], (sf1.st_size - f1_skip)/3, sf1.st_size, f1_skip);
+ bu_log("\t%s: %7zu pixels (%8zu bytes, skipping %7zu)\n",
+ argv[1], (sf2.st_size - f2_skip)/3, sf2.st_size, f2_skip);
+ }
+ bu_exit(1, "ERROR: Cannot pixcmp due to different images sizes
(unimplemented).\n");
}
- if (!print_bytes) {
- f1_skip *= 3;
- f2_skip *= 3;
- }
-
/* skip requested pixels/bytes in FILE1 */
if (f1_skip && fseek(f1, f1_skip, SEEK_SET)) {
bu_log("ERROR: Unable to seek %zd %s%s in FILE1\n",
Modified: brlcad/branches/bioh/bench/run.sh
===================================================================
--- brlcad/branches/bioh/bench/run.sh 2020-10-01 13:13:00 UTC (rev 77302)
+++ brlcad/branches/bioh/bench/run.sh 2020-10-01 13:15:27 UTC (rev 77303)
@@ -613,18 +613,14 @@
fi
# sanity check: make sure $CMP runs
-echo "" > tmp1
-echo "" > tmp2
-out=`echo "" | eval \"$CMP\" tmp1 tmp2 2>&1`
+out=`echo "" | eval \"$CMP\" - - 2>&1`
ret=$?
if test ! "x${ret}" = "x0" ; then
$ECHO
$ECHO "ERROR: CMP does not seem to work as expected"
$ECHO " (output was [$out])"
- rm -f tmp1 tmp2
exit 2
fi
-rm -f tmp1 tmp2
# sanity check: make sure $ELP runs
out=`eval \"$ELP\" 0 2>&1`
Index: brlcad/branches/bioh/doc
===================================================================
--- brlcad/branches/bioh/doc 2020-10-01 13:13:00 UTC (rev 77302)
+++ brlcad/branches/bioh/doc 2020-10-01 13:15:27 UTC (rev 77303)
Property changes on: brlcad/branches/bioh/doc
___________________________________________________________________
Modified: svn:mergeinfo
## -1,5 +1,5 ##
/brlcad/branches/RELEASE/doc:57439,57447-57860,69901-69913,71917-72242,72525-72534,72826-72858,74376-74454,74964-75140,77145-77155
-/brlcad/branches/brep-debug/doc:61373,61375,61404,61427,61429,61470,61544,61567,61576,61999,62018,62094,62098,62107,62117,62406,62416-62519,62521-62584,62593-62614,62623,62658,62660-62674,62681-62771,62876,62901,62907,62910,62925,62928,62931-63025,63027,63051,63054-63056,63069,63071-63073,63122,63160-63161,63165,63171,63184,63187,63189-63190,63193-63196,63200,63202,63205-63210,63213,63219-63225,63232-63233,63236,63238,63338,63350-63353,63481,63618,63669,64173-64174,64176-64177,64229-64233,64242,64244,64360-64362,65165,65245,65249,65334,65833-65834,66370-66375,66931-66932,66934,67012-67015,67018-67019,67021-67022,67406,67740,67746-67748,67950,67952,68144-68145,68636,68640-68643,68820,69081,69109,69206,69289,69346,69460-69461,69582-69583,69719-69721,69857-69859,69927
+/brlcad/branches/brep-debug/doc:61373,61375,61404,61427,61429,61470,61544,61567,61576,61999,62018,62094,62098,62107,62117,62406,62416-62519,62521-62584,62593-62614,62623,62658,62660-62674,62681-62771,62876,62901,62907,62910,62925,62928,62931-63025,63027,63051,63054-63056,63069,63071-63073,63122,63160-63161,63165,63171,63184,63187,63189-63190,63193-63196,63200,63202,63205-63210,63213,63219-63225,63232-63233,63236,63238,63338,63350-63353,63481,63618,63669,64173-64174,64176-64177,64229-64233,64242,64244,64360-64362,65165,65245,65249,65334,65833-65834,66370-66375,66931-66932,66934,67012-67015,67018-67019,67021-67022,67406,67740,67746-67748,67950,67952,68144-68145,68636,68640-68643,68820,69081,69109,69206,69289,69346,69460-69461,69582-69583,69719-69721,69857-69859,69927,77226-77229
/brlcad/branches/bullet/doc:62518
/brlcad/branches/cmake/doc:43219
/brlcad/branches/dm-fb-merge/doc:75426-76198
## -8,4 +8,4 ##
/brlcad/branches/osg/doc:62110-62113
/brlcad/branches/prep-cache/doc:68236-68933
/brlcad/branches/tcltk86/doc:68300-75257
-/brlcad/trunk/doc:75728-75834,75934-76134,76148-76154,76160-76351,76386-76505,76641-76653,76685-76859,76862-77219
\ No newline at end of property
+/brlcad/trunk/doc:75728-75834,75934-76134,76148-76154,76160-76351,76386-76505,76641-76653,76685-76859,76862-77302
\ No newline at end of property
Modified: brlcad/branches/bioh/doc/docbook/CMakeLists.txt
===================================================================
--- brlcad/branches/bioh/doc/docbook/CMakeLists.txt 2020-10-01 13:13:00 UTC
(rev 77302)
+++ brlcad/branches/bioh/doc/docbook/CMakeLists.txt 2020-10-01 13:15:27 UTC
(rev 77303)
@@ -36,6 +36,7 @@
add_subdirectory(articles)
add_subdirectory(books)
+add_subdirectory(devguides)
add_subdirectory(lessons)
add_subdirectory(presentations)
add_subdirectory(specifications)
Modified: brlcad/branches/bioh/doc/docbook/system/mann/analyze.xml
===================================================================
--- brlcad/branches/bioh/doc/docbook/system/mann/analyze.xml 2020-10-01
13:13:00 UTC (rev 77302)
+++ brlcad/branches/bioh/doc/docbook/system/mann/analyze.xml 2020-10-01
13:15:27 UTC (rev 77303)
@@ -10,9 +10,7 @@
<refnamediv xml:id="name">
<refname>analyze</refname>
<refpurpose>
- Displays the rotation and fallback angles, surface area, and
- plane equation for each face of the ARB specified on the command line.
The total
- surface area, volume, and the length of each edge are also displayed.
+ Report and/or compute analytical information about the listed objects.
</refpurpose>
</refnamediv>
@@ -20,39 +18,243 @@
<refsynopsisdiv xml:id="synopsis">
<cmdsynopsis sepchar=" ">
<command>analyze</command>
- <arg choice="req"
rep="norepeat"><replaceable>arb_name</replaceable></arg>
+ <arg choice="opt" rep="repeat"><replaceable>options</replaceable></arg>
+ <arg choice="opt"
rep="norepeat"><replaceable>subcommand</replaceable></arg>
</cmdsynopsis>
+ <variablelist>
+
+ <varlistentry><term></term><listitem>
+ <cmdsynopsis sepchar=" ">
+ <command>summarize</command>
+ <arg choice="req" rep="repeat">obj</arg>
+ </cmdsynopsis>
+ </listitem></varlistentry>
+
+ <varlistentry><term></term><listitem>
+ <cmdsynopsis sepchar=" ">
+ <command>intersect</command>
+ <arg choice="opt" rep="repeat"><replaceable>options</replaceable></arg>
+ <arg choice="req" rep="repeat">obj1 obj2 [...]</arg>
+ </cmdsynopsis>
+ </listitem></varlistentry>
+
+ <varlistentry><term></term><listitem>
+ <cmdsynopsis sepchar=" ">
+ <command>subtract</command>
+ <arg choice="opt" rep="repeat"><replaceable>options</replaceable></arg>
+ <arg choice="req" rep="repeat">obj1 obj2 [...]</arg>
+ </cmdsynopsis>
+ </listitem></varlistentry>
+ </variablelist>
</refsynopsisdiv>
<refsection xml:id="description"><title>DESCRIPTION</title>
<para>
- The <command>analyze</command> command displays the rotation and fallback
- angles, surface area, and plane equation for each face of the ARB
specified
- on the command line. The total surface area, volume, and the length of
each
- edge are also displayed. If executed while editing an ARB, the arb_name
may
- be omitted, and the ARB being edited will be analyzed.
+ The <command>analyze</command> command provides an array of reporting and
+ shape generation capabilities. The classic behavior (and the behavior
users
+ will see if calling without specifying a subcommand) is a report
summarizing
+ geometric information about the specified solid(s). This behavior may
also
+ be explicitly invoked by the <command>summarize</command> subcommand.
</para>
+
+ <para>
+ The <command>intersect</command> will take the first object specified and
+ intersect it with any subsequently specified objects - in effect,
building
+ up a new object with the geoemtry common to all objects specified.
+ </para>
+
+ <para>
+ The <command>subtract</command> will take the first object specified and
+ subtract from it any subsequently specified objects.
+ </para>
+
</refsection>
<refsection xml:id="examples"><title>EXAMPLES</title>
- <para>
- The example shows how to display information about an ARB's rotation and
- fallback angles, surface area, and plane equation for its face.
- Edge information is also displayed.
- </para>
<example><title>Analyze a particular <emphasis>ARB</emphasis></title>
+ <para>
+ <prompt>mged></prompt> <userinput>analyze box.s</userinput>
+ </para>
+ <literallayout>
+box.s: ARB8
+ 1 (30.0283, -5.21153, -16.3791)
+ 2 (30.0283, 21.5812, -16.3791)
+ 3 (30.0283, 21.5812, 10.4137)
+ 4 (30.0283, -5.21153, 10.4137)
+ 5 (3.23558, -5.21153, -16.3791)
+ 6 (3.23558, 21.5812, -16.3791)
+ 7 (3.23558, 21.5812, 10.4137)
+ 8 (3.23558, -5.21153, 10.4137)
++------+---------------------------+-------------------------------------------------+--------------+
+| FACE | ROT FB | PLANE EQUATION
| SURFACE AREA |
++------+---------------------------+-------------------------------------------------+--------------+
+| 1234 | 0.00000000 0.00000000 | 1.00000000 0.00000000 0.00000000
30.02833557 | 717.85172729 |
+| 5678 | 180.00000000 -0.00000000 | -1.00000000 -0.00000000 -0.00000000
-3.23558044 | 717.85172729 |
+| 1584 | 270.00000000 -0.00000000 | -0.00000000 -1.00000000 -0.00000000
5.21152973 | 717.85172729 |
+| 2376 | 90.00000000 -0.00000000 | -0.00000000 1.00000000 -0.00000000
21.58122540 | 717.85172729 |
+| 1265 | 0.00000000 -90.00000000 | -0.00000000 0.00000000 -1.00000000
16.37908936 | 717.85172729 |
+| 4378 | 0.00000000 90.00000000 | 0.00000000 -0.00000000 1.00000000
10.41366577 | 717.85172729 |
++------+---------------------------+-------------------------------------------------+--------------+
+
+
+--------------------+--------------------+--------------------+--------------------+
+ | EDGE LENGTH | EDGE LENGTH | EDGE LENGTH | EDGE
LENGTH |
+
+--------------------+--------------------+--------------------+--------------------+
+ | 12 26.79275513 | 23 26.79275513 | 34 26.79275513 | 14
26.79275513 |
+ | 15 26.79275513 | 56 26.79275513 | 26 26.79275513 | 67
26.79275513 |
+ | 78 26.79275513 | 58 26.79275513 | 48 26.79275513 | 37
26.79275513 |
+
+--------------------+--------------------+--------------------+--------------------+
+
+ +-------------------------------+
+ | Volume = 19233.22554681 |
+ | Surface Area = 4307.11036376 |
+ | Gallons = 0.00508088 |
+ +-------------------------------+
+ </literallayout>
+ </example>
+
+ <example><title>Analyze a particular <emphasis>TOR</emphasis></title>
<para>
- <prompt>mged></prompt> <userinput>analyze arb_name</userinput>
+ <prompt>mged></prompt> <userinput>analyze tor</userinput>
</para>
+ <literallayout>
+tor: torus (TOR)
+ V (4.91624, -32.8022, 31.7118), r1=25.4 (A), r2=5.08 (H)
+ N=(0, 1, 0)
+ A=(0, -0, 1)
+ B=(1, 0, -0)
+ vector to inner edge = (0, -0, 20.32)
+ vector to outer edge = (0, -0, 30.48)
+
+ Centroid: (4.91624, -32.8022, 31.7118)
+
+ +-------------------------------+
+ | Volume = 12938.70529707 |
+ | Surface Area = 5093.97853992 |
+ | Gallons = 0.00341804 |
+ +-------------------------------+
+ </literallayout>
+ </example>
+
+ <example><title>Points inside a sphere</title>
+
<para>
- Rotation and fallback angles, surface area, and plane equation for
- each face of the ARB specified on the command line are displayed along
- with edge information.
+ <prompt>mged></prompt> <userinput>l sph.s</userinput>
</para>
+ <literallayout>
+sph.s: ellipsoid (ELL)
+ V (0, 0, 0)
+ A (10, 0, 0) mag=10
+ B (0, 10, 0) mag=10
+ C (0, 0, 10) mag=10
+ A direction cosines=(0, 90, 90)
+ A rotation angle=0, fallback angle=0
+ B direction cosines=(90, 0, 90)
+ B rotation angle=90, fallback angle=0
+ C direction cosines=(90, 90, 0)
+ C rotation angle=0, fallback angle=90
+ </literallayout>
+
+ <para>
+ <prompt>mged></prompt> <userinput>l pnts.s</userinput>
+ </para>
+ <literallayout>
+pnts.s: Point Cloud (PNTS)
+Total number of points: 6
+Default scale: 0.000000
+point#, (point)
+1, (2.000000 2.000000 2.000000)
+2, (0.000000 0.000000 -5.000000)
+3, (0.000000 0.000000 10.000000)
+4, (0.000000 0.000000 20.000000)
+5, (10.000000 0.000000 10.000000)
+6, (0.000000 10.000000 20.000000)
+ </literallayout>
+
+ <para>
+ <prompt>mged></prompt> <userinput>analyze intersect -o inside.s
pnts.s sph.s</userinput>
+ </para>
+ <literallayout>
+3
+ </literallayout>
+
+ <para>
+ <prompt>mged></prompt> <userinput>l inside.s</userinput>
+ </para>
+ <literallayout>
+inside.s: Point Cloud (PNTS)
+Total number of points: 3
+Default scale: 0.000000
+point#, (point)
+1, (0.000000 0.000000 10.000000)
+2, (0.000000 0.000000 -5.000000)
+3, (2.000000 2.000000 2.000000)
+ </literallayout>
+
</example>
+
+
+ <example><title>Points outside a sphere</title>
+
+ <para>
+ <prompt>mged></prompt> <userinput>l sph.s</userinput>
+ </para>
+ <literallayout>
+sph.s: ellipsoid (ELL)
+ V (0, 0, 0)
+ A (10, 0, 0) mag=10
+ B (0, 10, 0) mag=10
+ C (0, 0, 10) mag=10
+ A direction cosines=(0, 90, 90)
+ A rotation angle=0, fallback angle=0
+ B direction cosines=(90, 0, 90)
+ B rotation angle=90, fallback angle=0
+ C direction cosines=(90, 90, 0)
+ C rotation angle=0, fallback angle=90
+ </literallayout>
+
+ <para>
+ <prompt>mged></prompt> <userinput>l pnts.s</userinput>
+ </para>
+ <literallayout>
+pnts.s: Point Cloud (PNTS)
+Total number of points: 6
+Default scale: 0.000000
+point#, (point)
+1, (2.000000 2.000000 2.000000)
+2, (0.000000 0.000000 -5.000000)
+3, (0.000000 0.000000 10.000000)
+4, (0.000000 0.000000 20.000000)
+5, (10.000000 0.000000 10.000000)
+6, (0.000000 10.000000 20.000000)
+ </literallayout>
+
+ <para>
+ <prompt>mged></prompt> <userinput>analyze subtract -o outside.s
pnts.s sph</userinput>
+ </para>
+ <literallayout>
+3
+ </literallayout>
+
+ <para>
+ <prompt>mged></prompt> <userinput>l outside.s</userinput>
+ </para>
+ <literallayout>
+outside.s: Point Cloud (PNTS)
+Total number of points: 3
+Default scale: 0.000000
+point#, (point)
+1, (0.000000 10.000000 20.000000)
+2, (10.000000 0.000000 10.000000)
+3, (0.000000 0.000000 20.000000)
+ </literallayout>
+
+
+ </example>
+
+
</refsection>
<refsection xml:id="author"><title>AUTHOR</title>
Modified: brlcad/branches/bioh/doc/docbook/system/mann/kill.xml
===================================================================
--- brlcad/branches/bioh/doc/docbook/system/mann/kill.xml 2020-10-01
13:13:00 UTC (rev 77302)
+++ brlcad/branches/bioh/doc/docbook/system/mann/kill.xml 2020-10-01
13:15:27 UTC (rev 77303)
@@ -1,61 +1,79 @@
<refentry xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="kill">
-<refmeta>
- <refentrytitle>KILL</refentrytitle>
- <manvolnum>nged</manvolnum>
- <refmiscinfo class="source">BRL-CAD</refmiscinfo>
- <refmiscinfo class="manual">BRL-CAD User Commands</refmiscinfo>
-</refmeta>
+ <refmeta>
+ <refentrytitle>KILL</refentrytitle>
+ <manvolnum>nged</manvolnum>
+ <refmiscinfo class="source">BRL-CAD</refmiscinfo>
+ <refmiscinfo class="manual">BRL-CAD User Commands</refmiscinfo>
+ </refmeta>
-<refnamediv xml:id="name">
- <refname>kill</refname>
- <refpurpose>Deletes specified <emphasis>objects</emphasis> from the current
database.
- </refpurpose>
-</refnamediv>
+ <refnamediv xml:id="name">
+ <refname>kill</refname>
+ <refpurpose>Deletes specified <emphasis>objects</emphasis> from the
current database.
+ </refpurpose>
+ </refnamediv>
-<!-- body begins here -->
-<refsynopsisdiv xml:id="synopsis">
- <cmdsynopsis sepchar=" ">
- <command>kill</command>
- <arg choice="opt" rep="norepeat">-f</arg>
- <arg choice="req" rep="norepeat"><replaceable>objects</replaceable></arg>
- </cmdsynopsis>
-</refsynopsisdiv>
+ <!-- body begins here -->
+ <refsynopsisdiv xml:id="synopsis">
+ <cmdsynopsis sepchar=" ">
+ <command>kill</command>
+ <arg choice="opt" rep="norepeat">-f</arg>
+ <arg choice="req" rep="norepeat"><replaceable>objects</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
-<refsection xml:id="description"><title>DESCRIPTION</title>
+ <refsection xml:id="description"><title>DESCRIPTION</title>
<para>
- Deletes the specified <emphasis>objects</emphasis> from the current
database.
- This command affects only the <emphasis>objects</emphasis> actually
listed on the command line. If a combination is killed, its members are
not affected. If the <emphasis>-f </emphasis>option is specified, then kill
will not complain if some, or all, of the <emphasis>objects</emphasis>
specified do not actually exist in the database. Note that the
<emphasis>objects</emphasis> are killed immediately. There is no need for a
<command> write file</command> command in MGED, and there is no
<command>undo</command> command. <emphasis remap="B" role="bold">Use this
command with caution.</emphasis> Other commands that remove objects from
the database are <command>killall</command> and <command>killtree
</command>.
+ Deletes the specified <emphasis>objects</emphasis> from the current
database. This command
+ affects only the <emphasis>objects</emphasis> actually listed on the
command line. If a
+ combination is killed, its members are not affected. If the
<emphasis>-f</emphasis>option
+ is specified, then kill will not complain if some, or all, of the
<emphasis>objects</emphasis>
+ specified do not actually exist in the database. Note that the
<emphasis>objects</emphasis>
+ are killed immediately. There is no need for a <command>write
file</command> command in MGED,
+ and there is no <command>undo</command> command. <emphasis remap="B"
role="bold">Use this
+ command with caution.</emphasis> Other commands that remove objects from
the database are
+ <command>killall</command> and <command>killtree</command>.
</para>
-</refsection>
+ <para>
+ The <option>-q</option> option may be added to suppress database object
lookup messages
+ reporting failure, which will otherwise let the user know an invalid
object was specified.
+ </para>
+ </refsection>
-<refsection xml:id="examples"><title>EXAMPLES</title>
-
- <para>The example shows the use of the <command>kill</command> command to
delete specified objects from the database.
+ <refsection xml:id="examples"><title>EXAMPLES</title>
+ <para>
+ The example shows the use of the <command>kill</command> command to delete
specified objects
+ from the database.
</para>
<example><title>Delete objects from the database.</title>
- <variablelist>
- <varlistentry>
- <term><prompt>mged></prompt> <userinput>kill group1 region2
shapeb</userinput></term>
- <listitem>
- <para>Deletes <emphasis>group1, region2</emphasis>, and
<emphasis>shapeb</emphasis> from the database.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
+ <variablelist>
+ <varlistentry>
+ <term><prompt>mged></prompt> <userinput>kill group1 region2
shapeb</userinput></term>
+ <listitem>
+ <para>
+ Deletes <emphasis>group1, region2</emphasis>, and
<emphasis>shapeb</emphasis> from
+ the database.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
</example>
-</refsection>
+ </refsection>
-<refsection xml:id="author"><title>AUTHOR</title><para>BRL-CAD
Team</para></refsection>
+ <refsection xml:id="author"><title>AUTHOR</title>
+ <para>
+ BRL-CAD Team
+ </para>
+ </refsection>
-<refsection xml:id="bug_reports"><title>BUG REPORTS</title>
+ <refsection xml:id="bug_reports"><title>BUG REPORTS</title>
<para>
Reports of bugs or problems should be submitted via electronic
mail to <email>[email protected]</email>
</para>
-</refsection>
+ </refsection>
</refentry>
Modified: brlcad/branches/bioh/doc/legal/embedded/SPSR.txt
===================================================================
--- brlcad/branches/bioh/doc/legal/embedded/SPSR.txt 2020-10-01 13:13:00 UTC
(rev 77302)
+++ brlcad/branches/bioh/doc/legal/embedded/SPSR.txt 2020-10-01 13:15:27 UTC
(rev 77303)
@@ -48,6 +48,42 @@
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
+
+Uses PlyVertexMini.h from geogram:
+https://github.com/alicevision/geogram/blob/master/src/lib/geogram/third_party/PoissonRecon/PlyVertexMini.h
+
+Geogram is licensed under the 3-clauses BSD License (also called "Revised
+BSD License", "New BSD License", or "Modified BSD License"):
+
+Copyright (c) 2012-2014, Bruno Levy All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer. Redistributions in binary
+form must reproduce the above copyright notice, this list of conditions and
+the following disclaimer in the documentation and/or other materials
+provided with the distribution. Neither the name of the ALICE Project-Team
+nor the names of its contributors may be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+If you modify this software, you should include a notice giving the name of
+the person performing the modification, the date of modification, and the
+reason for such modification.
+
file:/include/bg/spsr.h
file:/src/other/libspsr/Src/Allocator.h
file:/src/other/libspsr/Src/Array.h
@@ -80,8 +116,7 @@
file:/src/other/libspsr/Src/Octree.inl
file:/src/other/libspsr/Src/PPolynomial.h
file:/src/other/libspsr/Src/PPolynomial.inl
-file:/src/other/libspsr/Src/Ply.h
-file:/src/other/libspsr/Src/PlyFile.cpp
+file:/src/other/libspsr/Src/PlyVertexMini.h
file:/src/other/libspsr/Src/PointStream.h
file:/src/other/libspsr/Src/PointStream.inl
file:/src/other/libspsr/Src/PoissonRecon.cpp
Modified: brlcad/branches/bioh/doc/legal/other/CMakeLists.txt
===================================================================
--- brlcad/branches/bioh/doc/legal/other/CMakeLists.txt 2020-10-01 13:13:00 UTC
(rev 77302)
+++ brlcad/branches/bioh/doc/legal/other/CMakeLists.txt 2020-10-01 13:15:27 UTC
(rev 77303)
@@ -16,7 +16,6 @@
openscenegraph.txt
poly2tri.txt
proj-4.txt
- SPSR.txt
stepcode.txt
tcl.txt
tkhtml.txt
Deleted: brlcad/branches/bioh/doc/legal/other/SPSR.txt
===================================================================
--- brlcad/branches/bioh/doc/legal/other/SPSR.txt 2020-10-01 13:13:00 UTC
(rev 77302)
+++ brlcad/branches/bioh/doc/legal/other/SPSR.txt 2020-10-01 13:15:27 UTC
(rev 77303)
@@ -1,25 +0,0 @@
-Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
modification,
-are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
list of
-conditions and the following disclaimer. Redistributions in binary form must
reproduce
-the above copyright notice, this list of conditions and the following
disclaimer
-in the documentation and/or other materials provided with the distribution.
-
-Neither the name of the Johns Hopkins University nor the names of its
contributors
-may be used to endorse or promote products derived from this software without
specific
-prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY
-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO THE IMPLIED
WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT
-SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN
-ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH
-DAMAGE.
Index: brlcad/branches/bioh/include
===================================================================
--- brlcad/branches/bioh/include 2020-10-01 13:13:00 UTC (rev 77302)
+++ brlcad/branches/bioh/include 2020-10-01 13:15:27 UTC (rev 77303)
Property changes on: brlcad/branches/bioh/include
___________________________________________________________________
Modified: svn:mergeinfo
## -1,5 +1,5 ##
/brlcad/branches/RELEASE/include:57439,57447-57860,69901-69913,71915-72242,72525-72534,72826-72858,74376-74454,74964-75140,75372-75681,76726-76768
-/brlcad/branches/brep-debug/include:61373,61375,61404,61427,61429,61470,61544,61567,61576,61999,62018,62094,62098,62107,62117,62406,62416-62519,62521-62584,62593-62614,62623,62658,62660-62674,62681-62771,62876,62901,62907,62910,62925,62928,62931-63025,63027,63051,63054-63056,63069,63071-63073,63122,63160-63161,63165,63171,63184,63187,63189-63190,63193-63196,63200,63202,63205-63210,63213,63219-63225,63232-63233,63236,63238,63338,63350-63353,63481,63618,63669,64173-64174,64176-64177,64229-64233,64242,64244,64360-64362,65165,65245,65249,65334,65833-65834,66370-66375,66931-66932,66934,67012-67015,67018-67019,67021-67022,67406,67740,67746-67748,67950,67952,68144-68145,68636,68640-68643,68820,69081,69109,69206,69289,69346,69460-69461,69582-69583,69719-69721,69857-69859,69927
+/brlcad/branches/brep-debug/include:61373,61375,61404,61427,61429,61470,61544,61567,61576,61999,62018,62094,62098,62107,62117,62406,62416-62519,62521-62584,62593-62614,62623,62658,62660-62674,62681-62771,62876,62901,62907,62910,62925,62928,62931-63025,63027,63051,63054-63056,63069,63071-63073,63122,63160-63161,63165,63171,63184,63187,63189-63190,63193-63196,63200,63202,63205-63210,63213,63219-63225,63232-63233,63236,63238,63338,63350-63353,63481,63618,63669,64173-64174,64176-64177,64229-64233,64242,64244,64360-64362,65165,65245,65249,65334,65833-65834,66370-66375,66931-66932,66934,67012-67015,67018-67019,67021-67022,67406,67740,67746-67748,67950,67952,68144-68145,68636,68640-68643,68820,69081,69109,69206,69289,69346,69460-69461,69582-69583,69719-69721,69857-69859,69927,77226-77229
/brlcad/branches/bullet/include:62518
/brlcad/branches/cmake/include:43219
/brlcad/branches/dm-fb-merge/include:75426-76198
## -9,4 +9,4 ##
/brlcad/branches/osg/include:62110-62113
/brlcad/branches/prep-cache/include:68236-68933
/brlcad/branches/tcltk86/include:68300-75257
-/brlcad/trunk/include:75728-75834,75891-75926,75986-76146,76148-76154,76160-76351,76386-76505,76641-76859,76862-77219
\ No newline at end of property
+/brlcad/trunk/include:75728-75834,75891-75926,75986-76146,76148-76154,76160-76351,76386-76505,76641-76859,76862-77302
\ No newline at end of property
Modified: brlcad/branches/bioh/include/ged/commands.h
===================================================================
--- brlcad/branches/bioh/include/ged/commands.h 2020-10-01 13:13:00 UTC (rev
77302)
+++ brlcad/branches/bioh/include/ged/commands.h 2020-10-01 13:15:27 UTC (rev
77303)
@@ -860,6 +860,11 @@
*/
GED_EXPORT extern int ged_stat(struct ged *gedp, int argc, const char *argv[]);
+
+
+/* Debugging command for brep plotting */
+GED_EXPORT extern int ged_dplot(struct ged *gedp, int argc, const char
*argv[]);
+
/** @} */
Modified: brlcad/branches/bioh/src/conv/fast4-g.c
===================================================================
--- brlcad/branches/bioh/src/conv/fast4-g.c 2020-10-01 13:13:00 UTC (rev
77302)
+++ brlcad/branches/bioh/src/conv/fast4-g.c 2020-10-01 13:15:27 UTC (rev
77303)
@@ -38,6 +38,7 @@
#include "bu/app.h"
#include "bu/debug.h"
#include "bu/getopt.h"
+#include "bu/path.h"
#include "rt/db4.h"
#include "vmath.h"
#include "nmg.h"
@@ -2839,8 +2840,12 @@
rewind(fpin);
/* Make an ID record if no vehicle card was found */
- if (!vehicle[0])
- mk_id_units(fpout, argv[bu_optind], "in");
+ if (!vehicle[0]) {
+ struct bu_vls fname = BU_VLS_INIT_ZERO;
+ bu_path_component(&fname, argv[bu_optind], BU_PATH_BASENAME);
+ mk_id_units(fpout, bu_vls_cstr(&fname), "in");
+ bu_vls_free(&fname);
+ }
if (!quiet)
bu_log("Building components....\n");
Modified: brlcad/branches/bioh/src/libbrep/CMakeLists.txt
===================================================================
--- brlcad/branches/bioh/src/libbrep/CMakeLists.txt 2020-10-01 13:13:00 UTC
(rev 77302)
+++ brlcad/branches/bioh/src/libbrep/CMakeLists.txt 2020-10-01 13:15:27 UTC
(rev 77303)
@@ -33,6 +33,7 @@
cdt/mesh.cpp
cdt/ovlps_simple.cpp
cdt/tri_isect.cpp
+ debug_plot.cpp
intersect.cpp
tools/tools.cpp
opennurbs_ext.cpp
Modified: brlcad/branches/bioh/src/libbrep/boolean.cpp
===================================================================
--- brlcad/branches/bioh/src/libbrep/boolean.cpp 2020-10-01 13:13:00 UTC
(rev 77302)
+++ brlcad/branches/bioh/src/libbrep/boolean.cpp 2020-10-01 13:15:27 UTC
(rev 77303)
@@ -21,6 +21,8 @@
*
* Evaluate NURBS booleans (union, intersection and difference).
*
+ * Additional documentation can be found in the "NURBS Boolean Evaluation
+ * Development Guide" docbook article (bool_eval_development.html).
*/
#include "common.h"
@@ -31,6 +33,7 @@
#include <queue>
#include <set>
#include <map>
+#include <sstream>
#include "bio.h"
@@ -43,21 +46,16 @@
#include "brep/ray.h"
#include "brep/util.h"
+#include "debug_plot.h"
#include "brep_except.h"
+#include "brep_defines.h"
+DebugPlot *dplot = NULL;
// Whether to output the debug messages about b-rep booleans.
#define DEBUG_BREP_BOOLEAN 0
-// tol value used in ON_Intersect()s. We use a smaller tolerance than the
-// default one 0.001.
-#define INTERSECTION_TOL 1e-4
-// tol value used in ON_3dVector::IsParallelTo(). We use a smaller tolerance
-// than the default one ON_PI/180.
-#define ANGLE_TOL ON_PI/1800.0
-
-
struct IntersectPoint {
ON_3dPoint m_pt; // 3D intersection point
double m_seg_t; // param on the loop curve
@@ -104,7 +102,7 @@
};
-HIDDEN void
+void
append_to_polycurve(ON_Curve *curve, ON_PolyCurve &polycurve);
// We link the SSICurves that share an endpoint, and form this new structure,
// which has many similar behaviors as ON_Curve, e.g. PointAt(), Reverse().
@@ -344,7 +342,7 @@
}
-HIDDEN void
+void
append_to_polycurve(ON_Curve *curve, ON_PolyCurve &polycurve)
{
// use this function rather than ON_PolyCurve::Append() to avoid
@@ -3445,7 +3443,7 @@
std::set<int> *unused = i < face_count1 ? &unused1 : &unused2;
std::set<int> *intact = i < face_count1 ? &finalform1 : &finalform2;
int curr_index = i < face_count1 ? i : i - face_count1;
- if (face.BoundingBox().MinimumDistanceTo(brep->BoundingBox()) >
ON_ZERO_TOLERANCE) {
+ if (face.BoundingBox().MinimumDistanceTo(brep->BoundingBox()) >
INTERSECTION_TOL) {
switch (operation) {
case BOOLEAN_UNION:
intact->insert(curr_index);
@@ -3483,8 +3481,8 @@
if (unused2.find(j) == unused2.end() && finalform2.find(j) ==
finalform2.end()) {
// If the two faces don't interact according to their
bounding boxes,
// they won't be a source of events - otherwise, they must
be checked.
- fastf_t disjoint =
brep1->m_F[i].BoundingBox().MinimumDistanceTo(brep2->m_F[j].BoundingBox());
- if (!(disjoint > ON_ZERO_TOLERANCE)) {
+ fastf_t face_dist =
brep1->m_F[i].BoundingBox().MinimumDistanceTo(brep2->m_F[j].BoundingBox());
+ if (face_dist <= INTERSECTION_TOL) {
intersection_candidates.insert(std::pair<int, int>(i,
j));
}
}
@@ -3563,6 +3561,10 @@
if (results <= 0) {
continue;
}
+
+ dplot->SSX(events, brep1, brep1->m_F[i].m_si, brep2,
brep2->m_F[j].m_si);
+ dplot->WriteLog();
+
ON_SimpleArray<ON_Curve *> face1_curves, face2_curves;
for (int k = 0; k < events.Count(); k++) {
if (events[k].m_type == ON_SSX_EVENT::ssx_tangent ||
@@ -3590,6 +3592,8 @@
}
}
}
+ dplot->ClippedFaceCurves(surf1, surf2, face1_curves,
face2_curves);
+ dplot->WriteLog();
if (DEBUG_BREP_BOOLEAN) {
// Look for coplanar faces
@@ -3603,7 +3607,6 @@
}
}
-
}
}
@@ -3694,6 +3697,7 @@
}
splitted[j]->m_rev = false;
+ splitted[j]->m_belong_to_final = TrimmedFace::NOT_BELONG;
switch (face_location) {
case INSIDE_BREP:
if (operation == BOOLEAN_INTERSECT ||
@@ -3798,6 +3802,8 @@
for (int i = 0; i < original_faces.Count(); i++) {
TrimmedFace *first = original_faces[i];
ON_ClassArray<LinkedCurve> linked_curves = link_curves(curves_array[i]);
+ dplot->LinkedCurves(first->m_face->SurfaceOf(), linked_curves);
+ dplot->WriteLog();
ON_SimpleArray<TrimmedFace *> splitted = split_trimmed_face(first,
linked_curves);
trimmed_faces.Append(splitted);
@@ -3826,6 +3832,9 @@
categorize_trimmed_faces(trimmed_faces, brep1, brep2, surf_tree1,
surf_tree2, operation);
+ dplot->SplitFaces(trimmed_faces);
+ dplot->WriteLog();
+
for (int i = 0; i < surf_tree1.Count(); i++) {
delete surf_tree1[i];
}
@@ -3914,6 +3923,14 @@
int
ON_Boolean(ON_Brep *evaluated_brep, const ON_Brep *brep1, const ON_Brep
*brep2, op_type operation)
{
+ static int calls = 0;
+ ++calls;
+ std::ostringstream prefix;
+ prefix << "bool" << calls;
+ dplot = new DebugPlot(prefix.str().c_str());
+ dplot->Surfaces(brep1, brep2);
+ dplot->WriteLog();
+
ON_ClassArray<ON_SimpleArray<TrimmedFace *> > trimmed_faces;
try {
/* Deal with the trivial cases up front */
@@ -3934,14 +3951,17 @@
}
evaluated_brep->ShrinkSurfaces();
evaluated_brep->Compact();
+ dplot->WriteLog();
return 0;
}
trimmed_faces = get_evaluated_faces(brep1, brep2, operation);
} catch (InvalidBooleanOperation &e) {
bu_log("%s", e.what());
+ dplot->WriteLog();
return -1;
} catch (GeometryGenerationError &e) {
bu_log("%s", e.what());
+ dplot->WriteLog();
return -1;
}
@@ -3999,6 +4019,10 @@
bu_log("%s", ON_String(ws).Array());
}
+ dplot->WriteLog();
+ delete dplot;
+ dplot = NULL;
+
return 0;
}
Copied: brlcad/branches/bioh/src/libbrep/brep_defines.h (from rev 77302,
brlcad/trunk/src/libbrep/brep_defines.h)
===================================================================
--- brlcad/branches/bioh/src/libbrep/brep_defines.h
(rev 0)
+++ brlcad/branches/bioh/src/libbrep/brep_defines.h 2020-10-01 13:15:27 UTC
(rev 77303)
@@ -0,0 +1,71 @@
+/* B R E P _ D E F I N E S . H
+ * BRL-CAD
+ *
+ * Copyright (c) 2014 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 brep_defines.h
+ *
+ * Private defines.
+ *
+ */
+
+// The maximal depth for subdivision - trade-off between accuracy and
+// performance.
+#define NR_MAX_DEPTH 8
+#define MAX_PCI_DEPTH NR_MAX_DEPTH
+#define MAX_PSI_DEPTH NR_MAX_DEPTH
+#define MAX_CCI_DEPTH NR_MAX_DEPTH
+#define MAX_CSI_DEPTH NR_MAX_DEPTH
+#define MAX_SSI_DEPTH NR_MAX_DEPTH
+
+// Used to prevent an infinite loop in the unlikely event that we
+// can't provide a good starting point for the Newton-Raphson
+// Iteration.
+#define NR_MAX_ITERATIONS 100
+#define PCI_MAX_ITERATIONS NR_MAX_ITERATIONS
+#define PSI_MAX_ITERATIONS NR_MAX_ITERATIONS
+#define CCI_MAX_ITERATIONS NR_MAX_ITERATIONS
+#define CSI_MAX_ITERATIONS NR_MAX_ITERATIONS
+#define SSI_MAX_ITERATIONS NR_MAX_ITERATIONS
+
+// We make the default tolerance for PSI the same as that of curve and
+// surface intersections defined by openNURBS (see opennurbs_curve.h
+// and opennurbs_surface.h).
+#define NR_DEFAULT_TOLERANCE 0.001
+#define PCI_DEFAULT_TOLERANCE NR_DEFAULT_TOLERANCE
+#define PSI_DEFAULT_TOLERANCE NR_DEFAULT_TOLERANCE
+#define CCI_DEFAULT_TOLERANCE NR_DEFAULT_TOLERANCE
+#define CSI_DEFAULT_TOLERANCE NR_DEFAULT_TOLERANCE
+#define SSI_DEFAULT_TOLERANCE NR_DEFAULT_TOLERANCE
+
+// tol value used in ON_Intersect()s. We use a smaller tolerance than the
+// default one 0.001.
+#define INTERSECTION_TOL 1e-4
+
+// tol value used in ON_3dVector::IsParallelTo(). We use a smaller tolerance
+// than the default one ON_PI/180.
+#define ANGLE_TOL ON_PI/1800.0
+
+/*
+ * Local Variables:
+ * tab-width: 8
+ * mode: C
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Copied: brlcad/branches/bioh/src/libbrep/debug_plot.cpp (from rev 77302,
brlcad/trunk/src/libbrep/debug_plot.cpp)
===================================================================
--- brlcad/branches/bioh/src/libbrep/debug_plot.cpp
(rev 0)
+++ brlcad/branches/bioh/src/libbrep/debug_plot.cpp 2020-10-01 13:15:27 UTC
(rev 77303)
@@ -0,0 +1,990 @@
+/* D E B U G _ P L O T . C P P
+ * BRL-CAD
+ *
+ * Copyright (c) 2014 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 debug_plot.cpp
+ *
+ * DebugPlot implementation. Currently borrows code from librt to
+ * handle the creation of vlists for brep geometry and conversion of
+ * those vlists to unix plot files.
+ */
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include "bu/log.h"
+#include "bn.h"
+#include "raytrace.h"
+#include "vmath.h"
+#include "debug_plot.h"
+#include "brep_except.h"
+
+static unsigned char surface1_color[] = {0, 0, 62};
+static unsigned char surface2_color[] = {62, 0, 0};
+static unsigned char surface1_highlight_color[] = {56, 56, 255};
+static unsigned char surface2_highlight_color[] = {255, 56, 56};
+
+static unsigned char tangent_color[] = {255, 255, 255};
+static unsigned char transverse_color[] = {255, 255, 0};
+static unsigned char overlap_color[] = {0, 255, 0};
+
+static unsigned char accepted_outerloop_color[] = {0, 255, 0};
+static unsigned char accepted_innerloop_color[] = {255, 0, 0};
+static unsigned char unknown_outerloop_color[] = {158, 158, 0};
+static unsigned char unknown_innerloop_color[] = {158, 158, 0};
+static unsigned char rejected_outerloop_color[] = {0, 62, 0};
+static unsigned char rejected_innerloop_color[] = {62, 0, 0};
+
+DebugPlot::DebugPlot(const char *basename) :
+ prefix(basename),
+ have_surfaces(false),
+ brep1_surf_count(0),
+ brep2_surf_count(0),
+ linked_curve_count(0)
+{
+ BU_LIST_INIT(&vlist_free_list);
+}
+
+DebugPlot::~DebugPlot()
+{
+ struct bn_vlist *vp;
+ while (BU_LIST_WHILE(vp, bn_vlist, &vlist_free_list)) {
+ BU_LIST_DEQUEUE(&(vp->l));
+ bu_free((char *)vp, "bn_vlist");
+ }
+}
+
+int
+DebugPlot::SurfacePairs(void)
+{
+ return (int)intersecting_surfaces.size();
+}
+
+int
+DebugPlot::IntersectingIsocurves(int ssx_idx)
+{
+ int max_isocsx_idx = (int)ssx_isocsx_events.size() - 1;
+ if (ssx_idx < 0 || ssx_idx > max_isocsx_idx) {
+ std::cerr << "DebugPlot::IntersectingIsocurves passed invalid ssx
index.\n";
+ return 0;
+ }
+ return (int)ssx_isocsx_events[ssx_idx].size();
+}
+
+int
+DebugPlot::LinkedCurves(void)
+{
+ return linked_curve_count;
+}
+
+HIDDEN void
+rt_vlist_to_uplot(FILE *fp, const struct bu_list *vhead)
+{
+ struct bn_vlist *vp;
+
+ for (BU_LIST_FOR(vp, bn_vlist, vhead)) {
+ int i;
+ int nused = vp->nused;
+ const int *cmd = vp->cmd;
+ point_t *pt = vp->pt;
+
+ for (i = 0; i < nused; i++, cmd++, pt++) {
+ switch (*cmd) {
+ case BN_VLIST_POLY_START:
+ case BN_VLIST_TRI_START:
+ break;
+ case BN_VLIST_POLY_MOVE:
+ case BN_VLIST_LINE_MOVE:
+ case BN_VLIST_TRI_MOVE:
+ pdv_3move(fp, *pt);
+ break;
+ case BN_VLIST_POLY_DRAW:
+ case BN_VLIST_POLY_END:
+ case BN_VLIST_LINE_DRAW:
+ case BN_VLIST_TRI_DRAW:
+ case BN_VLIST_TRI_END:
+ pdv_3cont(fp, *pt);
+ break;
+ default:
+ bu_log("rt_vlist_to_uplot: unknown vlist cmd x%x\n",
+ *cmd);
+ }
+ }
+ }
+}
+
+HIDDEN void
+write_plot_to_file(
+ const char *filename,
+ const struct bu_list *vhead,
+ const unsigned char *color)
+{
+ FILE *fp = fopen(filename, "w");
+
+ if (!color) {
+ unsigned char clr[] = {255, 0, 0};
+ color = clr;
+ }
+
+ pl_linmod(fp, "solid");
+ pl_color(fp, color[0], color[1], color[2]);
+ rt_vlist_to_uplot(fp, vhead);
+
+ fclose(fp);
+}
+
+void
+DebugPlot::WriteLog()
+{
+ std::ostringstream filename;
+
+ // First write out empty plots of different colors, we use this to
+ // "erase" unwanted overlays when running the dplot command.
+ struct bu_list vhead;
+ BU_LIST_INIT(&vhead);
+ point_t origin = {0.0, 0.0, 0.0};
+ BN_ADD_VLIST(&vlist_free_list, &vhead, origin, BN_VLIST_LINE_MOVE);
+
+ filename << prefix << "_empty0.plot3";
+ write_plot_to_file(filename.str().c_str(), &vhead, tangent_color);
+ filename.str("");
+ filename << prefix << "_empty1.plot3";
+ write_plot_to_file(filename.str().c_str(), &vhead, transverse_color);
+ filename.str("");
+ filename << prefix << "_empty2.plot3";
+ write_plot_to_file(filename.str().c_str(), &vhead, overlap_color);
+ filename.str("");
+ filename << prefix << "_empty3.plot3";
+ write_plot_to_file(filename.str().c_str(), &vhead, surface1_color);
+ filename.str("");
+ filename << prefix << "_empty4.plot3";
+ write_plot_to_file(filename.str().c_str(), &vhead, surface2_color);
+ filename.str("");
+ filename << prefix << "_empty5.plot3";
+ write_plot_to_file(filename.str().c_str(), &vhead,
surface1_highlight_color);
+ filename.str("");
+ filename << prefix << "_empty6.plot3";
+ write_plot_to_file(filename.str().c_str(), &vhead,
surface2_highlight_color);
+ filename.str("");
+ filename << prefix << "_empty7.plot3";
+ write_plot_to_file(filename.str().c_str(), &vhead,
accepted_outerloop_color);
+ filename.str("");
+ filename << prefix << "_empty8.plot3";
+ write_plot_to_file(filename.str().c_str(), &vhead,
accepted_innerloop_color);
+ filename.str("");
+ filename << prefix << "_empty9.plot3";
+ write_plot_to_file(filename.str().c_str(), &vhead,
unknown_outerloop_color);
+ filename.str("");
+ filename << prefix << "_empty10.plot3";
+ write_plot_to_file(filename.str().c_str(), &vhead,
unknown_innerloop_color);
+ filename.str("");
+ filename << prefix << "_empty11.plot3";
+ write_plot_to_file(filename.str().c_str(), &vhead,
rejected_outerloop_color);
+ filename.str("");
+ filename << prefix << "_empty12.plot3";
+ write_plot_to_file(filename.str().c_str(), &vhead,
rejected_innerloop_color);
+
+ // create dplot log file
+ filename.str("");
+ filename << prefix << ".dplot";
+ FILE *fp = fopen(filename.str().c_str(), "w");
+
+ // write out surface-surface intersections
+ fprintf(fp, "surfaces %d %d\n", brep1_surf_count, brep2_surf_count);
+ for (size_t i = 0; i < intersecting_surfaces.size(); ++i) {
+ std::pair<int, int> intersecting = intersecting_surfaces[i];
+
+ int events, b1_isocurves, intersecting_isocurves, b1_clipped,
b2_clipped;
+
+ try {
+ events = ssx_events.at(i);
+ } catch (std::out_of_range &e) {
+ events = 0;
+ }
+ try {
+ std::pair<int, int> ccount = ssx_clipped_curves.at(i);
+ b1_clipped = ccount.first;
+ b2_clipped = ccount.second;
+ } catch (std::out_of_range &e) {
+ b1_clipped = b2_clipped = 0;
+ }
+ try {
+ b1_isocurves = ssx_isocsx_brep1_curves.at(i);
+ } catch (std::out_of_range &e) {
+ b1_isocurves = 0;
+ }
+ try {
+ intersecting_isocurves = (int)ssx_isocsx_events.at(i).size();
+ } catch (std::out_of_range &e) {
+ intersecting_isocurves = 0;
+ }
+
+ // b1si b2si finalevents b1ccurves b2ccurves b1_isocurve_xs
total_isocurve_xs isocsx0_event0 ...
+ fprintf(fp, "ssx %d %d %d %d %d %d %d", intersecting.first,
+ intersecting.second, events, b1_clipped, b2_clipped,
+ b1_isocurves, intersecting_isocurves);
+
+ if (ssx_isocsx_events.size() > i) {
+ for (size_t j = 0; j < ssx_isocsx_events[i].size(); ++j) {
+ fprintf(fp, " %d", ssx_isocsx_events[i][j]);
+ }
+ }
+ fprintf(fp, "\n");
+ }
+
+ // write out linked curve count
+ if (linked_curve_count > 0) {
+ fprintf(fp, "linkedcurves %d\n", linked_curve_count);
+ }
+
+ // write out split faces
+ size_t split_faces = split_face_outerloop_curves.size();
+ if (split_faces > 0) {
+ fprintf(fp, "splitfaces %d\n", (int)split_faces);
+ }
+ for (size_t i = 0; i < split_faces; ++i) {
+ fprintf(fp, "splitface %d %d %d\n", (int)i,
+ split_face_outerloop_curves[i],
+ split_face_innerloop_curves[i]);
+ }
+ fclose(fp);
+ BN_FREE_VLIST(&vlist_free_list, &vhead);
+}
+
+HIDDEN double
+find_next_t(const ON_Curve* crv, double start_t, double step, double max_dist)
+{
+ ON_Interval dom = crv->Domain();
+ ON_3dPoint prev_pt = crv->PointAt(dom.ParameterAt(start_t));
+ ON_3dPoint next_pt;
+
+ // ensure that (start + step) < 1.0
+ if (start_t + step > 1.0) {
+ step = 1.0 - start_t - BN_TOL_DIST;
+ }
+
+ // reduce step until next point is within tolerance
+ while (step > BN_TOL_DIST) {
+ next_pt = crv->PointAt(dom.ParameterAt(start_t + step));
+
+ if (prev_pt.DistanceTo(next_pt) <= max_dist) {
+ return start_t + step;
+ }
+ step /= 2.0;
+ }
+ // if we couldn't find a point within tolerance, give up and jump
+ // to end of domain
+ return 1.0;
+}
+
+void
+DebugPlot::Plot3DCurve(
+ const ON_Curve *crv,
+ const char *filename,
+ unsigned char *color,
+ struct bu_list *vlist /* = NULL */)
+{
+ struct bu_list vhead_tmp;
+ BU_LIST_INIT(&vhead_tmp);
+
+ struct bu_list *vhead = &vhead_tmp;
+ if (vlist) {
+ vhead = vlist;
+ }
+
+ ON_Interval crv_dom = crv->Domain();
+
+ // Insert first point.
+ point_t pt1;
+ ON_3dPoint p;
+ p = crv->PointAt(crv_dom.ParameterAt(0.0));
+ VMOVE(pt1, p);
+ BN_ADD_VLIST(&vlist_free_list, vhead, pt1, BN_VLIST_LINE_MOVE);
+
+ /* Dynamic sampling approach - start with an initial guess
+ * for the next point of one tenth of the domain length
+ * further down the domain from the previous value. Set a
+ * maximum physical distance between points of 100 times
+ * the model tolerance. Reduce the increment until the
+ * tolerance is satisfied, then add the point and use it
+ * as the starting point for the next calculation until
+ * the whole domain is finished. Perhaps it would be more
+ * ideal to base the tolerance on some fraction of the
+ * curve bounding box dimensions?
+ */
+ double t = 0.0;
+ while (t < 1.0) {
+ t = find_next_t(crv, t, 0.1, BN_TOL_DIST * 100);
+ p = crv->PointAt(crv_dom.ParameterAt(t));
+ VMOVE(pt1, p);
+
+ BN_ADD_VLIST(&vlist_free_list, vhead, pt1, BN_VLIST_LINE_DRAW);
+ }
+
+ if (!vlist) {
+ write_plot_to_file(filename, vhead, color);
+ BN_FREE_VLIST(&vlist_free_list, vhead);
+ }
+}
+
+void
+DebugPlot::Plot3DCurveFrom2D(
+ const ON_Surface *surf,
+ const ON_Curve *crv,
+ const char *filename,
+ unsigned char *color,
+ bool decorate /* = false */)
+{
+ struct bu_list vhead;
+ BU_LIST_INIT(&vhead);
+
+ ON_Interval crv_dom = crv->Domain();
+
+ ON_3dPoint p, uv;
+
+ // Insert first point.
+ point_t pt1, first_pt, last_pt, prev_pt;
+ ON_3dVector normal;
+ uv = crv->PointAt(crv_dom.ParameterAt(0.0));
+ surf->EvNormal(uv.x, uv.y, p, normal);
+ VMOVE(first_pt, p);
+
+ uv = crv->PointAt(crv_dom.ParameterAt(1.0));
+ surf->EvNormal(uv.x, uv.y, p, normal);
+ VMOVE(last_pt, p);
+
+ bool closed = false;
+ if (VNEAR_EQUAL(first_pt, last_pt, BN_TOL_DIST)) {
+ closed = true;
+ }
+
+ VMOVE(pt1, first_pt);
+ BN_ADD_VLIST(&vlist_free_list, &vhead, pt1, BN_VLIST_LINE_MOVE);
+
+ /* Dynamic sampling approach - start with an initial guess
+ * for the next point of one tenth of the domain length
+ * further down the domain from the previous value. Set a
+ * maximum physical distance between points of 100 times
+ * the model tolerance. Reduce the increment until the
+ * tolerance is satisfied, then add the point and use it
+ * as the starting point for the next calculation until
+ * the whole domain is finished. Perhaps it would be more
+ * ideal to base the tolerance on some fraction of the
+ * curve bounding box dimensions?
+ */
+ double t = 0.0;
+ bool first = true;
+ double min_mag = BN_TOL_DIST * 10.0;
+ double mag_tan = min_mag;
+ vect_t tangent = {0.0, 0.0, min_mag};
+ vect_t perp, barb;
+ while (t < 1.0) {
+ t = find_next_t(crv, t, 0.1, BN_TOL_DIST * 100);
+
+ uv = crv->PointAt(crv_dom.ParameterAt(t));
+ surf->EvNormal(uv.x, uv.y, p, normal);
+ VMOVE(prev_pt, pt1);
+ VMOVE(pt1, p);
+
+ if (first || !VNEAR_EQUAL(pt1, prev_pt, BN_TOL_DIST)) {
+ VSUB2(tangent, pt1, prev_pt);
+ }
+
+ if (decorate && first) {
+ first = false;
+
+ mag_tan = DIST_PNT_PNT(prev_pt, pt1);
+ mag_tan = FMAX(mag_tan, min_mag);
+
+ VUNITIZE(tangent);
+ VCROSS(perp, tangent, normal);
+
+ if (!closed) {
+ VSCALE(tangent, tangent, mag_tan);
+ VUNITIZE(perp);
+ VSCALE(perp, perp, mag_tan);
+
+ VADD3(barb, prev_pt, tangent, perp);
+ BN_ADD_VLIST(&vlist_free_list, &vhead, barb,
BN_VLIST_LINE_DRAW);
+ BN_ADD_VLIST(&vlist_free_list, &vhead, prev_pt,
BN_VLIST_LINE_MOVE);
+
+ VSCALE(perp, perp, -1.0);
+ VADD3(barb, prev_pt, tangent, perp);
+ BN_ADD_VLIST(&vlist_free_list, &vhead, barb,
BN_VLIST_LINE_DRAW);
+ BN_ADD_VLIST(&vlist_free_list, &vhead, prev_pt,
BN_VLIST_LINE_MOVE);
+ }
+ }
+ BN_ADD_VLIST(&vlist_free_list, &vhead, pt1, BN_VLIST_LINE_DRAW);
+ }
+ if (decorate) {
+ VUNITIZE(tangent);
+ VSCALE(tangent, tangent, -mag_tan);
+
+ VCROSS(perp, tangent, normal);
+ VUNITIZE(perp);
+ VSCALE(perp, perp, mag_tan);
+
+ VADD2(barb, pt1, perp);
+ if (!closed) {
+ VADD2(barb, barb, tangent);
+ }
+ BN_ADD_VLIST(&vlist_free_list, &vhead, barb, BN_VLIST_LINE_DRAW);
+ BN_ADD_VLIST(&vlist_free_list, &vhead, pt1, BN_VLIST_LINE_MOVE);
+
+ VSCALE(perp, perp, -1.0);
+ VADD2(barb, pt1, perp);
+ if (!closed) {
+ VADD2(barb, barb, tangent);
+ }
+ BN_ADD_VLIST(&vlist_free_list, &vhead, barb, BN_VLIST_LINE_DRAW);
+ }
+
+ write_plot_to_file(filename, &vhead, color);
+ BN_FREE_VLIST(&vlist_free_list, &vhead);
+}
+
+void
+DebugPlot::PlotBoundaryIsocurves(
+ struct bu_list *vlist,
+ const ON_Surface &surf,
+ int knot_dir)
+{
+ int surf_dir = 1 - knot_dir;
+ int knot_count = surf.SpanCount(surf_dir) + 1;
+
+ double *surf_knots = new double[knot_count];
+ surf.GetSpanVector(surf_dir, surf_knots);
+
+ // knots that can be boundaries of Bezier patches
+ ON_SimpleArray<double> surf_bknots;
+ surf_bknots.Append(surf_knots[0]);
+ for (int i = 1; i < knot_count; i++) {
+ if (surf_knots[i] > *(surf_bknots.Last())) {
+ surf_bknots.Append(surf_knots[i]);
+ }
+ }
+ delete[] surf_knots;
+
+ if (surf.IsClosed(surf_dir)) {
+ surf_bknots.Remove();
+ }
+
+ for (int i = 0; i < surf_bknots.Count(); i++) {
+ ON_Curve *surf_boundary_iso = surf.IsoCurve(knot_dir, surf_bknots[i]);
+ Plot3DCurve(surf_boundary_iso, NULL, NULL, vlist);
+ delete surf_boundary_iso;
+ }
+}
+
+void
+DebugPlot::PlotSurface(
+ const ON_Surface &surf,
+ const char *filename,
+ unsigned char *color)
+{
+ struct bu_list vhead;
+ BU_LIST_INIT(&vhead);
+
+ PlotBoundaryIsocurves(&vhead, surf, 0);
+ PlotBoundaryIsocurves(&vhead, surf, 1);
+
+ write_plot_to_file(filename, &vhead, color);
+
+ BN_FREE_VLIST(&vlist_free_list, &vhead);
+}
+
+
+void
+DebugPlot::Surfaces(const ON_Brep *brep1, const ON_Brep *brep2)
+{
+ if (!brep1 || !brep2) {
+ std::cerr << "error: dplot_surfaces: NULL args\n";
+ return;
+ }
+
+ brep1_surf_count = brep1->m_S.Count();
+ for (int i = 0; i < brep1->m_S.Count(); i++) {
+ ON_Surface *surf = brep1->m_S[i];
+ std::ostringstream filename;
+ filename << prefix << "_brep1_surface" << i << ".plot3";
+ PlotSurface(*surf, filename.str().c_str(), surface1_color);
+ }
+
+ brep2_surf_count = brep2->m_S.Count();
+ for (int i = 0; i < brep2->m_S.Count(); i++) {
+ ON_Surface *surf = brep2->m_S[i];
+ std::ostringstream filename;
+ filename << prefix << "_brep2_surface" << i << ".plot3";
+ PlotSurface(*surf, filename.str().c_str(), surface2_color);
+ }
+ have_surfaces = true;
+}
+
+int get_subcurve_inside_faces(const ON_Brep *brep1, const ON_Brep *brep2, int
face_i1, int face_i2, ON_SSX_EVENT *event);
+
+void
+DebugPlot::SSX(
+ const ON_ClassArray<ON_SSX_EVENT> &events,
+ const ON_Brep *brep1, int brep1_surf,
+ const ON_Brep *brep2, int brep2_surf)
+{
+ ON_Surface *surf;
+ std::ostringstream filename;
+
+ // create highlighted plot of brep1 surface if it doesn't exist
+ filename << prefix << "_highlight_brep1_surface" << brep1_surf << ".plot3";
+ if (!bu_file_exists(filename.str().c_str(), NULL)) {
+ surf = brep1->m_S[brep1_surf];
+ PlotSurface(*surf, filename.str().c_str(), surface1_highlight_color);
+ }
+
+ // create highlighted plot of brep2 surface if it doesn't exist
+ filename.str("");
+ filename << prefix << "_highlight_brep2_surface" << brep2_surf << ".plot3";
+ if (!bu_file_exists(filename.str().c_str(), NULL)) {
+ surf = brep2->m_S[brep2_surf];
+ PlotSurface(*surf, filename.str().c_str(), surface2_highlight_color);
+ }
+
+ // create plot of the intersections between these surfaces
+ surf = brep1->m_S[brep1_surf];
+ size_t ssx_idx = intersecting_surfaces.size();
+ int plot_count = 0;
+ for (int i = 0; i < events.Count(); ++i) {
+ filename.str("");
+ filename << prefix << "_ssx" << ssx_idx << "_event" << plot_count <<
+ ".plot3";
+
+ if (events[i].m_type == ON_SSX_EVENT::ssx_tangent) {
+ Plot3DCurveFrom2D(surf, events[i].m_curveA,
+ filename.str().c_str(), tangent_color, true);
+ ++plot_count;
+ } else if (events[i].m_type == ON_SSX_EVENT::ssx_transverse) {
+ Plot3DCurveFrom2D(surf, events[i].m_curveA,
+ filename.str().c_str(), transverse_color, true);
+ ++plot_count;
+ } else if (events[i].m_type == ON_SSX_EVENT::ssx_overlap) {
+ Plot3DCurveFrom2D(surf, events[i].m_curveA,
+ filename.str().c_str(), overlap_color, true);
+ ++plot_count;
+ }
+ }
+ // stash surface indices and event count
+ std::pair<int, int> ssx_pair(brep1_surf, brep2_surf);
+ intersecting_surfaces.push_back(ssx_pair);
+ ssx_events.push_back(plot_count);
+}
+
+void
+DebugPlot::IsoCSX(
+ const ON_SimpleArray<ON_X_EVENT> &events,
+ const ON_Curve *isocurve,
+ bool is_brep1_iso) // is the isocurve from brep1?
+{
+ size_t ssx_idx = intersecting_surfaces.size();
+
+ // create plot of the intersections between the curve and surface
+ while (ssx_isocsx_events.size() < (ssx_idx + 1)) {
+ ssx_isocsx_events.push_back(std::vector<int>());
+ }
+ size_t isocsx_idx = ssx_isocsx_events[ssx_idx].size();
+ int plot_count = 0;
+ for (int i = 0; i < events.Count(); ++i) {
+ if (events[i].m_type == ON_X_EVENT::csx_overlap) {
+ std::ostringstream filename;
+ filename << prefix << "_ssx" << ssx_idx << "_isocsx" << isocsx_idx
+ << "_event" << plot_count++ << ".plot3";
+
+ try {
+ ON_Curve *event_curve = sub_curve(isocurve, events[i].m_a[0],
+ events[i].m_a[1]);
+ Plot3DCurve(event_curve, filename.str().c_str(), overlap_color);
+ } catch (InvalidInterval &e) {
+ std::cerr << "error: IsoCSX event contains degenerate
interval\n";
+ }
+ }
+ }
+ if (plot_count) {
+ // create highlighted plot of isocurve if it doesn't already exist
+ std::ostringstream filename;
+ filename << prefix << "_highlight_ssx" << ssx_idx << "_isocurve" <<
+ isocsx_idx << ".plot3";
+ if (!bu_file_exists(filename.str().c_str(), NULL)) {
+ if (is_brep1_iso) {
+ Plot3DCurve(isocurve, filename.str().c_str(),
+ surface1_highlight_color);
+ } else {
+ Plot3DCurve(isocurve, filename.str().c_str(),
+ surface2_highlight_color);
+ }
+ }
+
+ // remember event count for this isocsx
+ ssx_isocsx_events[ssx_idx].push_back(plot_count);
+
+ // remember how many events are for brep1 isocurve and brep2 surface,
+ if (is_brep1_iso) {
+ while (ssx_isocsx_brep1_curves.size() < (ssx_idx + 1)) {
+ ssx_isocsx_brep1_curves.push_back(0);
+ }
+ ++ssx_isocsx_brep1_curves[ssx_idx];
+ }
+ }
+}
+
+void
+DebugPlot::ClippedFaceCurves(
+ const ON_Surface *surf1,
+ const ON_Surface *surf2,
+ const ON_SimpleArray<ON_Curve *> &face1_curves,
+ const ON_SimpleArray<ON_Curve *> &face2_curves)
+{
+ // plot clipped tangent/transverse/overlap curves
+ size_t ssx_idx = intersecting_surfaces.size() - 1;
+ for (int i = 0; i < face1_curves.Count(); ++i) {
+ std::ostringstream filename;
+ filename << prefix << "_ssx" << ssx_idx << "_brep1face_clipped_curve"
<< i << ".plot3";
+ Plot3DCurveFrom2D(surf1, face1_curves[i], filename.str().c_str(),
+ surface1_highlight_color, true);
+ }
+ for (int i = 0; i < face2_curves.Count(); ++i) {
+ std::ostringstream filename;
+ filename << prefix << "_ssx" << ssx_idx << "_brep2face_clipped_curve"
<< i << ".plot3";
+ Plot3DCurveFrom2D(surf2, face2_curves[i], filename.str().c_str(),
+ surface2_highlight_color, true);
+ }
+
+ while (ssx_clipped_curves.size() < (ssx_idx + 1)) {
+ ssx_clipped_curves.push_back(std::pair<int, int>(0, 0));
+ }
+ std::pair<int, int> counts(face1_curves.Count(), face2_curves.Count());
+ ssx_clipped_curves[ssx_idx] = counts;
+}
+
+struct TrimmedFace {
+ // curve segments in the face's outer loop
+ ON_SimpleArray<ON_Curve *> m_outerloop;
+ // several inner loops, each has some curves
+ std::vector<ON_SimpleArray<ON_Curve *> > m_innerloop;
+ const ON_BrepFace *m_face;
+ enum {
+ UNKNOWN = -1,
+ NOT_BELONG = 0,
+ BELONG = 1
+ } m_belong_to_final;
+ bool m_rev;
+
+ // Default constructor
+ TrimmedFace()
+ {
+ m_face = NULL;
+ m_belong_to_final = UNKNOWN;
+ m_rev = false;
+ }
+
+ // Destructor
+ ~TrimmedFace()
+ {
+ // Delete the curve segments if it's not belong to the result.
+ if (m_belong_to_final != BELONG) {
+ for (int i = 0; i < m_outerloop.Count(); i++) {
+ if (m_outerloop[i]) {
+ delete m_outerloop[i];
+ m_outerloop[i] = NULL;
+ }
+ }
+ for (unsigned int i = 0; i < m_innerloop.size(); i++) {
+ for (int j = 0; j < m_innerloop[i].Count(); j++) {
+ if (m_innerloop[i][j]) {
+ delete m_innerloop[i][j];
+ m_innerloop[i][j] = NULL;
+ }
+ }
+ }
+ }
+ }
+
+ TrimmedFace *Duplicate() const
+ {
+ TrimmedFace *out = new TrimmedFace();
+ out->m_face = m_face;
+ for (int i = 0; i < m_outerloop.Count(); i++) {
+ if (m_outerloop[i]) {
+ out->m_outerloop.Append(m_outerloop[i]->Duplicate());
+ }
+ }
+ out->m_innerloop = m_innerloop;
+ for (unsigned int i = 0; i < m_innerloop.size(); i++) {
+ for (int j = 0; j < m_innerloop[i].Count(); j++) {
+ if (m_innerloop[i][j]) {
+ out->m_innerloop[i][j] = m_innerloop[i][j]->Duplicate();
+ }
+ }
+ }
+ return out;
+ }
+};
+
+void
+DebugPlot::SplitFaces(
+ const ON_ClassArray<ON_SimpleArray<TrimmedFace *> > &split_faces)
+{
+ for (int i = 0; i < split_faces.Count(); ++i) {
+ for (int j = 0; j < split_faces[i].Count(); ++j) {
+ TrimmedFace *face = split_faces[i][j];
+
+ unsigned char *outerloop_color = unknown_outerloop_color;
+ unsigned char *innerloop_color = unknown_innerloop_color;
+ switch (face->m_belong_to_final) {
+ case TrimmedFace::NOT_BELONG:
+ outerloop_color = rejected_outerloop_color;
+ innerloop_color = rejected_innerloop_color;
+ break;
+ case TrimmedFace::BELONG:
+ outerloop_color = accepted_outerloop_color;
+ innerloop_color = accepted_innerloop_color;
+ break;
+ default:
+ outerloop_color = unknown_outerloop_color;
+ innerloop_color = unknown_innerloop_color;
+ }
+
+ int split_face_count = split_face_outerloop_curves.size();
+ for (int k = 0; k < face->m_outerloop.Count(); ++k) {
+ std::ostringstream filename;
+ filename << prefix << "_split_face" << split_face_count <<
+ "_outerloop_curve" << k << ".plot3";
+
+ Plot3DCurveFrom2D(face->m_face->SurfaceOf(),
+ face->m_outerloop[k], filename.str().c_str(),
+ outerloop_color);
+ }
+ split_face_outerloop_curves.push_back(face->m_outerloop.Count());
+
+ int innerloop_count = 0;
+ for (size_t k = 0; k < face->m_innerloop.size(); ++k) {
+ for (int l = 0; l < face->m_innerloop[k].Count(); ++l) {
+ std::ostringstream filename;
+ filename << prefix << "_split_face" << split_face_count <<
+ "_innerloop_curve" << innerloop_count++ << ".plot3";
+
+ Plot3DCurveFrom2D(face->m_face->SurfaceOf(),
+ face->m_innerloop[k][l], filename.str().c_str(),
+ innerloop_color);
+ }
+ }
+ split_face_innerloop_curves.push_back(innerloop_count);
+ }
+ }
+}
+
+void append_to_polycurve(ON_Curve *curve, ON_PolyCurve &polycurve);
+
+struct SSICurve {
+ ON_Curve *m_curve;
+
+ SSICurve()
+ {
+ m_curve = NULL;
+ }
+
+ SSICurve(ON_Curve *curve)
+ {
+ m_curve = curve;
+ }
+
+ SSICurve *Duplicate() const
+ {
+ SSICurve *out = new SSICurve();
+ if (out != NULL) {
+ *out = *this;
+ out->m_curve = m_curve->Duplicate();
+ }
+ return out;
+ }
+};
+
+struct LinkedCurve {
+private:
+ ON_Curve *m_curve; // an explicit storage of the whole curve
+public:
+ // The curves contained in this LinkedCurve, including
+ // the information needed by the connectivity graph
+ ON_SimpleArray<SSICurve> m_ssi_curves;
+
+ // Default constructor
+ LinkedCurve()
+ {
+ m_curve = NULL;
+ }
+
+ ~LinkedCurve()
+ {
+ if (m_curve) {
+ delete m_curve;
+ }
+ m_curve = NULL;
+ }
+
+ LinkedCurve &operator= (const LinkedCurve &_lc)
+ {
+ m_curve = _lc.m_curve ? _lc.m_curve->Duplicate() : NULL;
+ m_ssi_curves = _lc.m_ssi_curves;
+ return *this;
+ }
+
+ ON_3dPoint PointAtStart() const
+ {
+ if (m_ssi_curves.Count()) {
+ return m_ssi_curves[0].m_curve->PointAtStart();
+ } else {
+ return ON_3dPoint::UnsetPoint;
+ }
+ }
+
+ ON_3dPoint PointAtEnd() const
+ {
+ if (m_ssi_curves.Count()) {
+ return m_ssi_curves.Last()->m_curve->PointAtEnd();
+ } else {
+ return ON_3dPoint::UnsetPoint;
+ }
+ }
+
+ bool IsClosed() const
+ {
+ if (m_ssi_curves.Count() == 0) {
+ return false;
+ }
+ return PointAtStart().DistanceTo(PointAtEnd()) < ON_ZERO_TOLERANCE;
+ }
+
+ bool IsValid() const
+ {
+ // Check whether the curve has "gaps".
+ for (int i = 1; i < m_ssi_curves.Count(); i++) {
+ if
(m_ssi_curves[i].m_curve->PointAtStart().DistanceTo(m_ssi_curves[i -
1].m_curve->PointAtEnd()) >= ON_ZERO_TOLERANCE) {
+ bu_log("The LinkedCurve is not valid.\n");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool Reverse()
+ {
+ ON_SimpleArray<SSICurve> new_array;
+ for (int i = m_ssi_curves.Count() - 1; i >= 0; i--) {
+ if (!m_ssi_curves[i].m_curve->Reverse()) {
+ return false;
+ }
+ new_array.Append(m_ssi_curves[i]);
+ }
+ m_ssi_curves = new_array;
+ return true;
+ }
+
+ void Append(const LinkedCurve &lc)
+ {
+ m_ssi_curves.Append(lc.m_ssi_curves.Count(), lc.m_ssi_curves.Array());
+ }
+
+ void Append(const SSICurve &sc)
+ {
+ m_ssi_curves.Append(sc);
+ }
+
+ void AppendCurvesToArray(ON_SimpleArray<ON_Curve *> &arr) const
+ {
+ for (int i = 0; i < m_ssi_curves.Count(); i++) {
+ arr.Append(m_ssi_curves[i].m_curve->Duplicate());
+ }
+ }
+
+ const ON_Curve *Curve()
+ {
+ if (m_curve != NULL) {
+ return m_curve;
+ }
+ if (m_ssi_curves.Count() == 0 || !IsValid()) {
+ return NULL;
+ }
+ ON_PolyCurve *polycurve = new ON_PolyCurve;
+ for (int i = 0; i < m_ssi_curves.Count(); i++) {
+ append_to_polycurve(m_ssi_curves[i].m_curve->Duplicate(),
*polycurve);
+ }
+ m_curve = polycurve;
+ return m_curve;
+ }
+
+ const ON_3dPoint PointAt(double t)
+ {
+ const ON_Curve *c = Curve();
+ if (c == NULL) {
+ return ON_3dPoint::UnsetPoint;
+ }
+ return c->PointAt(t);
+ }
+
+ const ON_Interval Domain()
+ {
+ const ON_Curve *c = Curve();
+ if (c == NULL) {
+ return ON_Interval::EmptyInterval;
+ }
+ return c->Domain();
+ }
+
+ ON_Curve *SubCurve(double t1, double t2)
+ {
+ const ON_Curve *c = Curve();
+ if (c == NULL) {
+ return NULL;
+ }
+ try {
+ return sub_curve(c, t1, t2);
+ } catch (InvalidInterval &e) {
+ bu_log("%s", e.what());
+ return NULL;
+ }
+ }
+};
+
+void
+DebugPlot::LinkedCurves(
+ const ON_Surface *surf,
+ ON_ClassArray<LinkedCurve> &linked_curves)
+{
+ for (int i = 0; i < linked_curves.Count(); ++i) {
+ const ON_Curve *linked_curve = linked_curves[i].Curve();
+
+ std::ostringstream filename;
+ filename << prefix << "_linked_curve" << linked_curve_count++ <<
".plot3";
+
+ Plot3DCurveFrom2D(surf, linked_curve, filename.str().c_str(),
transverse_color);
+ }
+}
+
+// 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
Copied: brlcad/branches/bioh/src/libbrep/debug_plot.h (from rev 77302,
brlcad/trunk/src/libbrep/debug_plot.h)
===================================================================
--- brlcad/branches/bioh/src/libbrep/debug_plot.h
(rev 0)
+++ brlcad/branches/bioh/src/libbrep/debug_plot.h 2020-10-01 13:15:27 UTC
(rev 77303)
@@ -0,0 +1,141 @@
+/* D E B U G _ P L O T . H
+ * BRL-CAD
+ *
+ * Copyright (c) 2014 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 debug_plot.h
+ *
+ * Class used to write out unix plot files representing brep geometry
+ * and intersection events from various stages of brep boolean
+ * evaluation.
+ *
+ * Also outputs a parsable log file with implicit information about
+ * the output plot files.
+ */
+
+#ifndef DEBUG_PLOT_H
+#define DEBUG_PLOT_H
+#include "bu/list.h"
+#include "raytrace.h"
+
+struct TrimmedFace;
+struct LinkedCurve;
+
+class DebugPlot {
+public:
+ // prefix all dplot output files with 'basename'
+ DebugPlot(const char *basename);
+
+ ~DebugPlot();
+
+ // write plot files for all surfaces of two breps
+ void Surfaces(const ON_Brep *brep1, const ON_Brep *brep2);
+
+ // record a surface surface intersection
+ void SSX(
+ const ON_ClassArray<ON_SSX_EVENT> &events,
+ const ON_Brep *brep1, int brep1_surf,
+ const ON_Brep *brep2, int brep2_surf);
+
+ // record surface surface isocurve intersections
+ void IsoCSX(
+ const ON_SimpleArray<ON_X_EVENT> &events,
+ const ON_Curve *isocurve,
+ bool is_brep1_iso);
+
+ // record clipped surface-surface intersection curves
+ void ClippedFaceCurves(
+ const ON_Surface *surf1,
+ const ON_Surface *surf2,
+ const ON_SimpleArray<ON_Curve *> &face1_curves,
+ const ON_SimpleArray<ON_Curve *> &face2_curves);
+
+ // write out the log file that the dplot command references to
+ // navigate the generated plot files
+ void WriteLog();
+
+ // get the number of intersecting surface pairs recorded
+ int SurfacePairs();
+
+ // get the number of isocurves that intersect either surface in
+ // given surface pair
+ int IntersectingIsocurves(int ssx_idx);
+
+ // get the number of linked curves recorded
+ int LinkedCurves();
+
+ void SplitFaces(
+ const ON_ClassArray<ON_SimpleArray<TrimmedFace *> > &split_faces);
+
+ void LinkedCurves(
+ const ON_Surface *surf,
+ ON_ClassArray<LinkedCurve> &linked_curves);
+
+ void
+ Plot3DCurveFrom2D(
+ const ON_Surface *surf,
+ const ON_Curve *crv,
+ const char *filename,
+ unsigned char *color,
+ bool decorate = false
+ );
+
+ void
+ Plot3DCurve(
+ const ON_Curve *crv,
+ const char *filename,
+ unsigned char *color,
+ struct bu_list *vlist = NULL);
+
+private:
+ struct bu_list vlist_free_list;
+ std::string prefix;
+ bool have_surfaces;
+ int brep1_surf_count;
+ int brep2_surf_count;
+ int linked_curve_count;
+ std::vector< std::pair<int, int> > intersecting_surfaces; // ssx surface
index pairs
+ std::vector<int> ssx_events; // num final events of each ssx
+ std::vector< std::vector<int> > ssx_isocsx_events; // num events for each
isocsx of each ssx
+ std::vector<int> ssx_isocsx_brep1_curves; // num ssx isocsx events using
brep1 isocurves
+ std::vector< std::pair<int, int> > ssx_clipped_curves; // num clipped
intersection curves
+ std::vector<int> split_face_outerloop_curves;
+ std::vector<int> split_face_innerloop_curves;
+
+ void PlotSurface(
+ const ON_Surface &surf,
+ const char *filename,
+ unsigned char *color);
+
+ void
+ PlotBoundaryIsocurves(
+ struct bu_list *vlist,
+ const ON_Surface &surf,
+ int knot_dir);
+};
+
+#endif
+
+/*
+ * Local Variables:
+ * tab-width: 8
+ * mode: C
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Modified: brlcad/branches/bioh/src/libbrep/intersect.cpp
===================================================================
--- brlcad/branches/bioh/src/libbrep/intersect.cpp 2020-10-01 13:13:00 UTC
(rev 77302)
+++ brlcad/branches/bioh/src/libbrep/intersect.cpp 2020-10-01 13:15:27 UTC
(rev 77303)
@@ -21,6 +21,8 @@
*
* Implementation of intersection routines openNURBS left out.
*
+ * Additional documentation can be found in the "NURBS Boolean Evaluation
+ * Development Guide" docbook article (bool_eval_development.html).
*/
#include "common.h"
@@ -38,42 +40,15 @@
#include "brep/defines.h"
#include "brep/intersect.h"
#include "brep/util.h"
+#include "debug_plot.h"
#include "brep_except.h"
+#include "brep_defines.h"
+extern DebugPlot *dplot;
// Whether to output the debug messages about b-rep intersections.
static int DEBUG_BREP_INTERSECT = 0;
-// The maximal depth for subdivision - trade-off between accuracy and
-// performance.
-#define NR_MAX_DEPTH 8
-#define MAX_PCI_DEPTH NR_MAX_DEPTH
-#define MAX_PSI_DEPTH NR_MAX_DEPTH
-#define MAX_CCI_DEPTH NR_MAX_DEPTH
-#define MAX_CSI_DEPTH NR_MAX_DEPTH
-#define MAX_SSI_DEPTH NR_MAX_DEPTH
-
-
-// We make the default tolerance for PSI the same as that of curve and
-// surface intersections defined by openNURBS (see opennurbs_curve.h
-// and opennurbs_surface.h).
-#define NR_DEFAULT_TOLERANCE 0.001
-#define PCI_DEFAULT_TOLERANCE NR_DEFAULT_TOLERANCE
-#define PSI_DEFAULT_TOLERANCE NR_DEFAULT_TOLERANCE
-#define CCI_DEFAULT_TOLERANCE NR_DEFAULT_TOLERANCE
-#define CSI_DEFAULT_TOLERANCE NR_DEFAULT_TOLERANCE
-#define SSI_DEFAULT_TOLERANCE NR_DEFAULT_TOLERANCE
-
-// Used to prevent an infinite loop in the unlikely event that we
-// can't provide a good starting point for the Newton-Raphson
-// Iteration.
-#define NR_MAX_ITERATIONS 100
-#define PCI_MAX_ITERATIONS NR_MAX_ITERATIONS
-#define PSI_MAX_ITERATIONS NR_MAX_ITERATIONS
-#define CCI_MAX_ITERATIONS NR_MAX_ITERATIONS
-#define CSI_MAX_ITERATIONS NR_MAX_ITERATIONS
-#define SSI_MAX_ITERATIONS NR_MAX_ITERATIONS
-
class XEventProxy {
public:
XEventProxy(ON_X_EVENT::TYPE type);
@@ -2556,10 +2531,29 @@
return (pointA.DistanceTo(pointB) < isect_tol) && !std::isnan(uA) &&
!std::isnan(vA) && !std::isnan(uB) & !std::isnan(vB);
}
+// if curve end is greater than tol distance from pt, append a linear
+// segment to the curve so it extends to the pt
+HIDDEN void
+extend_curve_end_to_pt(ON_Curve *&curve, ON_3dPoint pt, double tol)
+{
+ ON_NurbsCurve *nc = curve->NurbsCurve();
+ if (nc->PointAtEnd().DistanceTo(pt) > tol) {
+ ON_LineCurve line_bridge(nc->PointAtEnd(), pt);
+ ON_NurbsCurve bridge;
+ if (line_bridge.GetNurbForm(bridge)) {
+ nc->Append(bridge);
+ }
+ delete curve;
+ curve = nc;
+ }
+}
+
HIDDEN ON_Curve *
link_curves(ON_Curve *&c1, ON_Curve *&c2)
{
+ extend_curve_end_to_pt(c1, c2->PointAtStart(), ON_ZERO_TOLERANCE);
+
ON_NurbsCurve *nc1 = c1->NurbsCurve();
ON_NurbsCurve *nc2 = c2->NurbsCurve();
if (nc1 && nc2) {
@@ -2578,6 +2572,16 @@
return NULL;
}
+// if curve start and end are within tolerance, append a linear
+// segment to the curve to close it completely so it passes
+// IsClosed() tests
+HIDDEN void
+fill_gap_if_closed(ON_Curve *&curve, double tol)
+{
+ if (curve->PointAtStart().DistanceTo(curve->PointAtEnd()) <= tol) {
+ extend_curve_end_to_pt(curve, curve->PointAtStart(), ON_ZERO_TOLERANCE);
+ }
+}
struct OverlapSegment {
ON_Curve *m_curve3d, *m_curveA, *m_curveB;
@@ -2969,17 +2973,10 @@
bool ret = false;
if (iso.overlap_t[0] < iso.overlap_t[1]) {
- bool at_first_knot = iso.src.knot.IsFirst();
- bool at_last_knot = iso.src.knot.IsLast();
- bool closed_at_iso = surf1->IsClosed(1 - iso.src.knot.dir) != 0;
+ int location = isocurve_surface_overlap_location(iso, surf1, surf2,
+ surf2_tree, isect_tol, isect_tol1);
- ret = true;
- if (closed_at_iso || (!at_first_knot && !at_last_knot)) {
- int location = isocurve_surface_overlap_location(iso, surf1,
- surf2, surf2_tree,
isect_tol, isect_tol1);
-
- ret = (location == ON_OVERLAP_BOUNDARY);
- }
+ ret = (location == ON_OVERLAP_BOUNDARY);
}
return ret;
}
@@ -3513,6 +3510,7 @@
HIDDEN void
find_overlap_boundary_curves(
ON_SimpleArray<OverlapSegment *> &overlaps,
+ ON_ClassArray<ON_SSX_EVENT> &csx_events,
ON_3dPointArray &isocurve_3d,
ON_2dPointArray &isocurveA_2d,
ON_2dPointArray &isocurveB_2d,
@@ -3554,6 +3552,9 @@
ON_Intersect(surf1_isocurve, surf2, events, isect_tol,
overlap_tol, 0, 0, 0, &overlap2d);
+ dplot->IsoCSX(events, surf1_isocurve, is_surfA_iso);
+ dplot->WriteLog();
+
append_csx_event_points(isocurve_3d, isocurve2_2d, events);
for (int k = 0; k < events.Count(); k++) {
@@ -3575,6 +3576,36 @@
if (curve_on_overlap_boundary) {
append_overlap_segments(overlaps, iso, overlap2d[k],
surf1);
+ } else {
+ // the intersection isn't part of a
+ // surface-surface overlap, but we want it all
+ // the same
+ ON_SimpleArray<OverlapSegment *> tmp_overlaps;
+
+ append_overlap_segments(tmp_overlaps, iso,
overlap2d[k], surf1);
+
+ for (int l = 0; l < tmp_overlaps.Count(); ++l) {
+ ON_SSX_EVENT ssx_event;
+
+ int ret = set_ssx_event_from_curves(ssx_event,
+ tmp_overlaps[l]->m_curve3d,
+ tmp_overlaps[l]->m_curveA,
+ tmp_overlaps[l]->m_curveB, surfA, surfB);
+ if (ret != 0) {
+ bu_log("warning: reverse failed.");
+ }
+ csx_events.Append(ssx_event);
+
+ // set the curves to NULL so they aren't
+ // deleted by destructors
+ tmp_overlaps[l]->m_curve3d = NULL;
+ tmp_overlaps[l]->m_curveA = NULL;
+ tmp_overlaps[l]->m_curveB = NULL;
+
+ ssx_event.m_curve3d = NULL;
+ ssx_event.m_curveA = NULL;
+ ssx_event.m_curveB = NULL;
+ }
}
}
}
@@ -3735,12 +3766,25 @@
ON_2dPointArray curve_uvA, curve_uvB, tmp_curve_uvA, tmp_curve_uvB;
ON_SimpleArray<OverlapSegment *> overlaps;
- find_overlap_boundary_curves(overlaps, tmp_curvept, tmp_curve_uvA,
+ ON_ClassArray<ON_SSX_EVENT> csx_events;
+
+ find_overlap_boundary_curves(overlaps, csx_events, tmp_curvept,
tmp_curve_uvA,
tmp_curve_uvB, surfA, surfB, treeA, treeB,
isect_tol, isect_tolA,
isect_tolB, overlap_tol);
+
split_overlaps_at_intersections(overlaps, surfA, surfB, treeA, treeB,
isect_tol, isect_tolA, isect_tolB);
+ // add csx_events
+ for (int i = 0; i < csx_events.Count(); ++i) {
+ x.Append(csx_events[i]);
+
+ // set the curves to NULL so they aren't deleted by destructor
+ csx_events[i].m_curve3d = NULL;
+ csx_events[i].m_curveA = NULL;
+ csx_events[i].m_curveB = NULL;
+ }
+
// find the neighbors for every overlap segment
ON_SimpleArray<bool> start_linked(overlaps.Count()),
end_linked(overlaps.Count());
for (int i = 0; i < overlaps.Count(); i++) {
@@ -3875,6 +3919,9 @@
delete overlaps[j];
overlaps[j] = NULL;
}
+ fill_gap_if_closed(overlaps[i]->m_curve3d, isect_tol);
+ fill_gap_if_closed(overlaps[i]->m_curveA, isect_tolA);
+ fill_gap_if_closed(overlaps[i]->m_curveB, isect_tolB);
}
}
Modified: brlcad/branches/bioh/src/libbrep/tests/CMakeLists.txt
===================================================================
--- brlcad/branches/bioh/src/libbrep/tests/CMakeLists.txt 2020-10-01
13:13:00 UTC (rev 77302)
+++ brlcad/branches/bioh/src/libbrep/tests/CMakeLists.txt 2020-10-01
13:15:27 UTC (rev 77303)
@@ -14,15 +14,9 @@
vsp.stp
)
-BRLCAD_ADDEXEC(brep_cdt_mesh brep_cdt_mesh.cpp "libbrep;libbg;libbn;libbu"
TEST)
+BRLCAD_ADDEXEC(test_brep_ppx ppx.cpp "libbrep" NO_INSTALL)
+add_test(NAME brep_ppx COMMAND test_brep_ppx)
-BRLCAD_ADDEXEC(test_point_intersect test_point_intersect.cpp "libbrep"
NO_STRICT NO_INSTALL)
-
-BRLCAD_ADDEXEC(test_curve_intersect test_curve_intersect.cpp "libbrep"
NO_STRICT NO_INSTALL)
-
-CMAKEFILES(${distcheck_files})
-CMAKEFILES(CMakeLists.txt)
-
# Local Variables:
# tab-width: 8
# mode: cmake
Copied: brlcad/branches/bioh/src/libbrep/tests/ppx.cpp (from rev 77302,
brlcad/trunk/src/libbrep/tests/ppx.cpp)
===================================================================
--- brlcad/branches/bioh/src/libbrep/tests/ppx.cpp
(rev 0)
+++ brlcad/branches/bioh/src/libbrep/tests/ppx.cpp 2020-10-01 13:15:27 UTC
(rev 77303)
@@ -0,0 +1,235 @@
+/* P P X . C P P
+ * BRL-CAD
+ *
+ * Copyright (c) 2014 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 ppx.cpp
+ *
+ * Point-point intersection tests.
+ *
+ */
+
+#define NOMINMAX
+
+#include "common.h"
+#include "bu.h"
+#include "brep.h"
+#include <limits>
+#include <sstream>
+#include <string>
+#include "../brep_defines.h"
+
+// Here we determine an upper limit on the magnitude of coordinate
+// values for test points.
+//
+// We need to be able to calculate point to point distance as:
+// sqrt((x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2)
+//
+// To prevent overflow, we must restrict the coordinate values such
+// that:
+// (x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2 <= DBL_MAX
+//
+// If we want to choose an upper limit M on the magnitude of a
+// coordinate value to enforce this constraint, the restriction
+// simplifies to:
+// coord1, coord2 in [-M, M] s.t.
+// (coord2 - coord1)^2 <= DBL_MAX / 3.0
+// => (coord2 - coord1) <= sqrt(DBL_MAX / 3.0)
+//
+// Knowing that the maximum value of (coord2 - coord1) is 2M, we can
+// solve for M:
+// 2M <= sqrt(DBL_MAX / 3.0)
+// => M <= sqrt(DBL_MAX / 3.0) / 2.0
+//
+// We choose to use a value slightly less than the true DBL_MAX for
+// the calculation to avoid the possibility that floating point error
+// causes [3.0 * sqrt(DBL_MAX / 3.0)^2 <= DBL_MAX] to be false.
+static const double NEAR_DBL_MAX =
+ std::numeric_limits<double>::max() -
+ std::numeric_limits<double>::round_error();
+
+static const double COORD_MAG_MAX = sqrt(NEAR_DBL_MAX / 3.0) / 2.0;
+
+class PPX_Input {
+public:
+ PPX_Input()
+ : tol(0.0)
+ {
+ }
+ ON_3dPoint ptA;
+ ON_3dPoint ptB;
+ ON_ClassArray<ON_PX_EVENT> events;
+ bool default_tol;
+ double tol;
+};
+
+class PPX_Output {
+public:
+ bool status;
+ ON_ClassArray<ON_PX_EVENT> events;
+
+ bool Equals(std::string &log, const PPX_Output &other);
+};
+
+static const double EVENT_EQUAL_TOL =
+ std::numeric_limits<double>::round_error();
+
+static bool
+point_events_equal(ON_PX_EVENT a, ON_PX_EVENT b)
+{
+ if (a.m_type != b.m_type) {
+ return false;
+ }
+ if (a.m_A.DistanceTo(b.m_A) >= EVENT_EQUAL_TOL) {
+ return false;
+ }
+ if (a.m_B.DistanceTo(b.m_B) >= EVENT_EQUAL_TOL) {
+ return false;
+ }
+ if (a.m_b.DistanceTo(b.m_b) >= EVENT_EQUAL_TOL) {
+ return false;
+ }
+ if (a.m_Mid.DistanceTo(b.m_Mid) >= EVENT_EQUAL_TOL) {
+ return false;
+ }
+ if (!ON_NearZero(a.m_radius - b.m_radius, EVENT_EQUAL_TOL)) {
+ return false;
+ }
+ return true;
+}
+
+bool
+PPX_Output::Equals(std::string &log, const PPX_Output &other)
+{
+ bool ret = true;
+ std::stringstream out;
+
+ if (status != other.status) {
+ out << "return status: " << std::boolalpha << status << " vs " <<
+ other.status << "\n";
+ ret = false;
+ }
+
+ if (events.Count() != other.events.Count()) {
+ out << "event count: " << events.Count() << " vs " <<
+ other.events.Count() << "\n";
+ ret = false;
+ } else {
+ for (int i = 0; i < events.Count(); ++i) {
+ if (!point_events_equal(other.events[i], events[i])) {
+ out << "event arrays don't match\n";
+ ret = false;
+ break;
+ }
+ }
+ }
+
+ log = out.str();
+
+ return ret;
+}
+
+void
+test_intersection(PPX_Input in, PPX_Output expected_out)
+{
+ PPX_Output out;
+
+ out.events = in.events;
+
+ if (in.default_tol) {
+ out.status = ON_Intersect(in.ptA, in.ptB, out.events);
+ } else {
+ out.status = ON_Intersect(in.ptA, in.ptB, out.events, in.tol);
+ }
+
+ std::string err_msg;
+ if (!expected_out.Equals(err_msg, out)) {
+ bu_exit(1, "Unexpected intersection result. Expected vs actual:\n%s",
+ err_msg.c_str());
+ }
+}
+
+static ON_PX_EVENT
+ppx_point_event(ON_3dPoint ptA, ON_3dPoint ptB)
+{
+ ON_PX_EVENT event;
+ event.m_type = ON_PX_EVENT::ppx_point;
+ event.m_A = ptA;
+ event.m_B = ptB;
+ event.m_b = ON_2dPoint(0.0, 0.0);
+ event.m_Mid = (ptA + ptB) * 0.5;
+ event.m_radius = ptA.DistanceTo(ptB) * 0.5;
+ return event;
+}
+
+static void
+test_equal_points(ON_3dPoint pt)
+{
+ ON_ClassArray<ON_PX_EVENT> events;
+ events.Append(ppx_point_event(pt, pt));
+
+ PPX_Output expected_output;
+ expected_output.status = true;
+ expected_output.events = events;
+
+ PPX_Input input;
+ input.ptA = input.ptB = pt;
+ input.default_tol = true;
+
+ test_intersection(input, expected_output);
+}
+
+static void
+do_equal_point_tests(void)
+{
+ std::vector<double> coord_vals;
+ coord_vals.push_back(-COORD_MAG_MAX);
+ coord_vals.push_back(-INTERSECTION_TOL);
+ coord_vals.push_back(0.0);
+ coord_vals.push_back(INTERSECTION_TOL);
+ coord_vals.push_back(COORD_MAG_MAX);
+
+ for (size_t i = 0; i < coord_vals.size(); ++i) {
+ for (size_t j = 0; j < coord_vals.size(); ++j) {
+ for (size_t k = 0; k < coord_vals.size(); ++k) {
+ ON_3dPoint test_pt(coord_vals[i], coord_vals[j],
+ coord_vals[k]);
+
+ test_equal_points(test_pt);
+ }
+ }
+ }
+}
+
+int
+main(int UNUSED(argc), const char *argv[])
+{
+ bu_setprogname(argv[0]);
+
+ do_equal_point_tests();
+
+ return 0;
+}
+
+// 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
Modified: brlcad/branches/bioh/src/libged/analyze/CMakeLists.txt
===================================================================
--- brlcad/branches/bioh/src/libged/analyze/CMakeLists.txt 2020-10-01
13:13:00 UTC (rev 77302)
+++ brlcad/branches/bioh/src/libged/analyze/CMakeLists.txt 2020-10-01
13:15:27 UTC (rev 77303)
@@ -6,9 +6,20 @@
${GED_INCLUDE_DIRS}
)
+set(analyze_srcs
+ analyze.cpp
+ arb8.cpp
+ arbn.cpp
+ ars.cpp
+ superell.cpp
+ sketch.cpp
+ util.cpp
+ op_pnts_vol.cpp
+ )
+
add_definitions(-DGED_PLUGIN)
-ged_plugin_library(ged-analyze SHARED analyze.c)
-target_link_libraries(ged-analyze libged libbu)
+ged_plugin_library(ged-analyze SHARED ${analyze_srcs})
+target_link_libraries(ged-analyze libged libanalyze libbu)
set_property(TARGET ged-analyze APPEND PROPERTY COMPILE_DEFINITIONS
BRLCADBUILD HAVE_CONFIG_H)
VALIDATE_STYLE(ged-analyze analyze.c)
PLUGIN_SETUP(ged-analyze ged)
@@ -15,7 +26,8 @@
CMAKEFILES(
CMakeLists.txt
- analyze.c
+ ${analyze_srcs}
+ ged_analyze.h
)
# Local Variables:
Deleted: brlcad/branches/bioh/src/libged/analyze/analyze.c
===================================================================
--- brlcad/branches/bioh/src/libged/analyze/analyze.c 2020-10-01 13:13:00 UTC
(rev 77302)
+++ brlcad/branches/bioh/src/libged/analyze/analyze.c 2020-10-01 13:15:27 UTC
(rev 77303)
@@ -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",
@@ Diff output truncated at 100000 characters. @@
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