aboutsummaryrefslogtreecommitdiff
path: root/src/graph/view3D
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2007-08-14 05:14:52 +0000
committerdos-reis <gdr@axiomatics.org>2007-08-14 05:14:52 +0000
commitab8cc85adde879fb963c94d15675783f2cf4b183 (patch)
treec202482327f474583b750b2c45dedfc4e4312b1d /src/graph/view3D
downloadopen-axiom-ab8cc85adde879fb963c94d15675783f2cf4b183.tar.gz
Initial population.
Diffstat (limited to 'src/graph/view3D')
-rw-r--r--src/graph/view3D/ChangeLog72
-rw-r--r--src/graph/view3D/Makefile.in74
-rw-r--r--src/graph/view3D/Makefile.pamphlet110
-rw-r--r--src/graph/view3D/buttons3d.c.pamphlet450
-rw-r--r--src/graph/view3D/closeView3d.c.pamphlet116
-rw-r--r--src/graph/view3D/component3d.c.pamphlet908
-rwxr-xr-xsrc/graph/view3D/contour.h195
-rwxr-xr-xsrc/graph/view3D/contour3d.c.out675
-rwxr-xr-xsrc/graph/view3D/contour_panel3d.c.out760
-rw-r--r--src/graph/view3D/control3d.c.pamphlet1076
-rwxr-xr-xsrc/graph/view3D/cpanel.h103
-rwxr-xr-xsrc/graph/view3D/draw.h73
-rwxr-xr-xsrc/graph/view3D/eventnames.h70
-rwxr-xr-xsrc/graph/view3D/globals.h163
-rwxr-xr-xsrc/graph/view3D/header.h386
-rw-r--r--src/graph/view3D/illuminate3d.c.pamphlet237
-rw-r--r--src/graph/view3D/lightbut3d.c.pamphlet173
-rw-r--r--src/graph/view3D/lighting3d.c.pamphlet628
-rw-r--r--src/graph/view3D/main3d.c.pamphlet670
-rw-r--r--src/graph/view3D/mesh3d.c.pamphlet156
-rw-r--r--src/graph/view3D/msort3d.c.pamphlet199
-rw-r--r--src/graph/view3D/pot3d.c.pamphlet118
-rwxr-xr-xsrc/graph/view3D/process.h40
-rw-r--r--src/graph/view3D/process3d.c.pamphlet1625
-rw-r--r--src/graph/view3D/project3d.c.pamphlet446
-rw-r--r--src/graph/view3D/quit3d.c.pamphlet193
-rw-r--r--src/graph/view3D/quitbut3d.c.pamphlet109
-rw-r--r--src/graph/view3D/save3d.c.pamphlet188
-rw-r--r--src/graph/view3D/savebut3d.c.pamphlet119
-rw-r--r--src/graph/view3D/smoothShade3d.c.pamphlet1143
-rw-r--r--src/graph/view3D/spadAction3d.c.pamphlet431
-rwxr-xr-xsrc/graph/view3D/static.h61
-rw-r--r--src/graph/view3D/stuff3d.c.pamphlet201
-rw-r--r--src/graph/view3D/surface3d.c.pamphlet870
-rw-r--r--src/graph/view3D/testcol.c.pamphlet623
-rw-r--r--src/graph/view3D/transform3d.c.pamphlet179
-rw-r--r--src/graph/view3D/viewport3d.c.pamphlet941
-rwxr-xr-xsrc/graph/view3D/volume.h169
-rw-r--r--src/graph/view3D/volume3d.c.pamphlet900
-rw-r--r--src/graph/view3D/write3d.c.pamphlet236
40 files changed, 15886 insertions, 0 deletions
diff --git a/src/graph/view3D/ChangeLog b/src/graph/view3D/ChangeLog
new file mode 100644
index 00000000..3d018ddf
--- /dev/null
+++ b/src/graph/view3D/ChangeLog
@@ -0,0 +1,72 @@
+2007-07-29 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Propagate libtoolization changes.
+ * Makefile.in: Regenerate.
+
+2006-11-26 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * buttons3d.c.pamphlet: Include axiom-c-macros.h
+ * closeView3d.c.pamphlet: Likewise.
+ * component3d.c.pamphlet: Likewise.
+ * control3d.c.pamphlet: Likewise.
+ * illuminate3d.c.pamphlet: Likewise.
+ * lightbut3d.c.pamphlet: Likewise.
+ * lighting3d.c.pamphlet: Likewise.
+ * main3d.c.pamphlet: Likewise.
+ * mesh3d.c.pamphlet: Likewise.
+ * msort3d.c.pamphlet: Likewise.
+ * pot3d.c.pamphlet: Likewise.
+ * process3d.c.pamphlet: Likewise.
+ * project3d.c.pamphlet: Likewise.
+ * quit3d.c.pamphlet: Likewise.
+ * quitbut3d.c.pamphlet: Likewise.
+ * save3d.c.pamphlet: Likewise.
+ * savebut3d.c.pamphlet: Likewise.
+ * smoothShade3d.c.pamphlet: Likewise.
+ * spadAction3d.c.pamphlet: Likewise.
+ * stuff3d.c.pamphlet: Likewise.
+ * surface3d.c.pamphlet: Likewise.
+ * testcol.c.pamphlet: Likewise.
+ * transform3d.c.pamphlet: Likewise.
+ * viewport3d.c.pamphlet: Likewise.
+ * volume3d.c.pamphlet: Likewise.
+ * write3d.c.pamphlet: Likewise.
+
+ * Makefile.pamphlet: Add support for OS that require extension for
+ executable binary files.
+ * Makefile.in: Regenerate.
+
+2006-11-24 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Use .$(OBJEXT) in lieu of plain .o.
+ (MIDINT, MIDOBJ, LIB, GDRAW, GDRAW_OBJS): Remove.
+ (Gfun_objects): Simplify.
+ (view3D_objects): Likewise.
+ (view3D_DEPENDENCIES): Remove explicit reference to libspad.a
+ (AXIOM_CFLAGS): New variable.
+ (%.$(OBJEXT)): Use it.
+ * Makefile.in: Regenerate.
+
+2006-10-08 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Remove references to ${MNT} throughout.
+ * Makefile.in: Regenerate.
+
+2006-09-18 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Simplify.
+ * Makefile.in: Regenerate.
+
+2006-09-11 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Use $(axiom_build_document) to tangle
+ pamphlets. Add support for out-of-source build.
+ * Makefile.in: Regenerate.
+
+2006-09-03 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.in: New.
+
+2006-08-06 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Remove explicit mention of X11 and Xpm.
diff --git a/src/graph/view3D/Makefile.in b/src/graph/view3D/Makefile.in
new file mode 100644
index 00000000..74739790
--- /dev/null
+++ b/src/graph/view3D/Makefile.in
@@ -0,0 +1,74 @@
+
+IN= $(axiom_src_srcdir)/graph/view3D
+
+# local include files shared by graphics
+LINC= $(axiom_src_srcdir)/graph/include
+
+# global include files shared by everyone
+GINC= $(axiom_src_srcdir)/include
+
+# bitmaps for cursors
+BIT= $(axiom_src_srcdir)/graph/include/purty
+
+build_libdir = $(abs_top_builddir)/src/lib
+
+bin_PROGRAMS = view3D$(EXEEXT)
+
+view3D_sources = buttons3d.c closeView3d.c component3d.c control3d.c \
+ illuminate3d.c lightbut3d.c lighting3d.c main3d.c \
+ mesh3d.c msort3d.c pot3d.c process3d.c project3d.c \
+ quitbut3d.c quit3d.c save3d.c savebut3d.c smoothShade3d.c \
+ spadAction3d.c stuff3d.c surface3d.c transform3d.c \
+ viewport3d.c volume3d.c write3d.c
+
+view3D_SOURCES = $(addsuffix .pamphlet, $(view3D_sources))
+
+view3D_objects = $(addprefix $(builddir)/, $(view3D_sources:.c=.lo))
+
+Gfun_objects = ../Gdraws/Gfun.lo
+
+
+view3D_LDADD = $(axiom_target_libdir)/libspad.la
+view3D_DEPENDENCIES = $(Gfun_objects)
+
+pamphlets = Makefile.pamphlet $(view3D_SOURCES)
+
+subdir = src/graph/view3D/
+
+AXIOM_CFLAGS = ${CCF} ${AXIOM_X11_CFLAGS} -I${LINC} -I${GINC} -I${IN} \
+ $(axiom_includes)
+
+HEADERS = ${IN}/header.h ${IN}/globals.h \
+ ${LINC}/component.h ${LINC}/view3D.h ${LINC}/tube.h \
+ ${LINC}/actions.h ${LINC}/viewCommand.h \
+ ${GINC}/view.h ${LINC}/G.h $(axiom_c_macros.h)
+
+.PHONY: all all-ax all-view3D
+all: all-ax
+all-ax all-view3D: stamp
+ @echo finished $(srcdir)
+
+stamp: $(axiom_target_libdir)/view3D$(EXEEXT)
+ @rm -f stamp
+ $(STAMP) stamp
+
+$(axiom_target_libdir)/view3D$(EXEEXT): $(view3D_objects) $(view3D_DEPENDENCIES)
+ $(LINK) -o $@ $(view3D_objects) $(Gfun_objects) \
+ $(view3D_LDADD) $(AXIOM_X11_LDFLAGS) -lm
+
+.PRECIOUS: %.lo
+.PRECIOUS: %.c
+
+%.lo: $(HEADERS)
+
+%.lo: %.c
+ $(COMPILE) -o $@ $(CFLAGS) $(AXIOM_CFLAGS) $<
+
+%.c: $(srcdir)/%.c.pamphlet
+ $(axiom_build_document) --tangle --output=$@ $<
+
+mostly-clean:
+
+clean-clean: mostlyclean-clean
+
+distclean-local: clean-local
diff --git a/src/graph/view3D/Makefile.pamphlet b/src/graph/view3D/Makefile.pamphlet
new file mode 100644
index 00000000..694219bb
--- /dev/null
+++ b/src/graph/view3D/Makefile.pamphlet
@@ -0,0 +1,110 @@
+%% Oh Emacs, this is a -*- Makefile -*-, so give me tabs.
+\documentclass{article}
+\usepackage{axiom}
+
+\title{no title}
+\author{The Axiom Team}
+
+\begin{document}
+\maketitle
+
+\begin{abstract}
+\end{abstract}
+\eject
+
+\tableofcontents
+\eject
+
+
+\section{environment}
+<<environment>>=
+
+IN= $(axiom_src_srcdir)/graph/view3D
+
+# local include files shared by graphics
+LINC= $(axiom_src_srcdir)/graph/include
+
+# global include files shared by everyone
+GINC= $(axiom_src_srcdir)/include
+
+# bitmaps for cursors
+BIT= $(axiom_src_srcdir)/graph/include/purty
+
+build_libdir = $(abs_top_builddir)/src/lib
+
+bin_PROGRAMS = view3D$(EXEEXT)
+
+view3D_sources = buttons3d.c closeView3d.c component3d.c control3d.c \
+ illuminate3d.c lightbut3d.c lighting3d.c main3d.c \
+ mesh3d.c msort3d.c pot3d.c process3d.c project3d.c \
+ quitbut3d.c quit3d.c save3d.c savebut3d.c smoothShade3d.c \
+ spadAction3d.c stuff3d.c surface3d.c transform3d.c \
+ viewport3d.c volume3d.c write3d.c
+
+view3D_SOURCES = $(addsuffix .pamphlet, $(view3D_sources))
+
+view3D_objects = $(addprefix $(builddir)/, $(view3D_sources:.c=.lo))
+
+Gfun_objects = ../Gdraws/Gfun.lo
+
+
+view3D_LDADD = $(axiom_target_libdir)/libspad.la
+view3D_DEPENDENCIES = $(Gfun_objects)
+
+pamphlets = Makefile.pamphlet $(view3D_SOURCES)
+@
+
+\section{view3D}
+<<view3D>>=
+$(axiom_target_libdir)/view3D$(EXEEXT): $(view3D_objects) $(view3D_DEPENDENCIES)
+ $(LINK) -o $@ $(view3D_objects) $(Gfun_objects) \
+ $(view3D_LDADD) $(AXIOM_X11_LDFLAGS) -lm
+
+.PRECIOUS: %.lo
+.PRECIOUS: %.c
+
+%.lo: $(HEADERS)
+
+%.lo: %.c
+ $(COMPILE) -o $@ $(CFLAGS) $(AXIOM_CFLAGS) $<
+
+%.c: $(srcdir)/%.c.pamphlet
+ $(axiom_build_document) --tangle --output=$@ $<
+@
+
+<<*>>=
+<<environment>>
+
+subdir = src/graph/view3D/
+
+AXIOM_CFLAGS = ${CCF} ${AXIOM_X11_CFLAGS} -I${LINC} -I${GINC} -I${IN} \
+ $(axiom_includes)
+
+HEADERS = ${IN}/header.h ${IN}/globals.h \
+ ${LINC}/component.h ${LINC}/view3D.h ${LINC}/tube.h \
+ ${LINC}/actions.h ${LINC}/viewCommand.h \
+ ${GINC}/view.h ${LINC}/G.h $(axiom_c_macros.h)
+
+.PHONY: all all-ax all-view3D
+all: all-ax
+all-ax all-view3D: stamp
+ @echo finished $(srcdir)
+
+stamp: $(axiom_target_libdir)/view3D$(EXEEXT)
+ @rm -f stamp
+ $(STAMP) stamp
+
+<<view3D>>
+
+mostly-clean:
+
+clean-clean: mostlyclean-clean
+
+distclean-local: clean-local
+@
+\eject
+
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/buttons3d.c.pamphlet b/src/graph/view3D/buttons3d.c.pamphlet
new file mode 100644
index 00000000..9727e581
--- /dev/null
+++ b/src/graph/view3D/buttons3d.c.pamphlet
@@ -0,0 +1,450 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D buttons3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _BUTTONS3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include "header.h"
+#include "cpanel.h"
+
+#include "all_3d.H1"
+#define BH 31 /* button window height */
+#define PH 80 /* potentiometer window height */
+#define XEDGE 5 /* leftmost button starts here */
+
+/*****************************************************
+ * int initButtons(buttons) *
+ * *
+ * Creates the fields for each button window in the *
+ * three dimensional control panel, and returns the *
+ * number of buttons created. *
+ * *
+ *****************************************************/
+
+int
+#ifdef _NO_PROTO
+initButtons (buttons)
+ buttonStruct *buttons;
+#else
+initButtons (buttonStruct *buttons)
+#endif
+{
+
+ int PBY = 297; /* panel button Y coordinate at which buttons appear */
+ int ii, num = 0;
+
+ /* Rotate, Zoom, and Translate Potentiometer Buttons */
+
+ /* Title: "Rotate" */
+ ii = rotate;
+ buttons[ii].buttonX = XEDGE; buttons[ii].buttonY = 85;
+ buttons[ii].buttonWidth = 110; buttons[ii].buttonHeight = PH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = yes; /* rotate is a potentiometer */
+ buttons[ii].mask = potMASK;
+ buttons[ii].textColor = 139; /* line color of rotate dial */
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Title: "Scale" */
+ ii = zoom;
+ buttons[ii].buttonX = 121; buttons[ii].buttonY = 85;
+ buttons[ii].buttonWidth = 58; buttons[ii].buttonHeight = PH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = yes; /* zoom(scale) is a potentiometer */
+ buttons[ii].mask = potMASK;
+ buttons[ii].textColor = 165; /* line color of scale arrow */
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+
+ /* Title: "Translate" */
+ ii = translate;
+ buttons[ii].buttonX = 185; buttons[ii].buttonY = 85;
+ buttons[ii].buttonWidth = 110; buttons[ii].buttonHeight = PH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = yes; /* translate is a potentiometer */
+ buttons[ii].mask = potMASK;
+ buttons[ii].textColor = 21; /* line color of translate arrows */
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* All the rest of the buttons are regular, toggle only buttons and
+ have the potentiometer variable set to "no". */
+
+ /* First Row of Buttons */
+ /* The four rendering mode buttons:
+ wireframe, hiddenline solid, hiddenline shaded and smooth shaded **/
+
+ /* Wirefram mesh */
+ ii = transparent;
+ buttons[ii].buttonX = XEDGE; buttons[ii].buttonY = PBY;
+ buttons[ii].buttonWidth = 45; buttons[ii].buttonHeight = BH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "Wire";
+ buttons[ii].textColor = modeColor;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Hidden surface mesh */
+ ii = opaqueMesh;
+ buttons[ii].buttonX = 55; buttons[ii].buttonY = PBY;
+ buttons[ii].buttonWidth = 53; buttons[ii].buttonHeight = BH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "Solid";
+ buttons[ii].textColor = modeColor;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Lambertian polygon fill with phong illumination model */
+ ii = render;
+ buttons[ii].buttonX = 113; buttons[ii].buttonY = PBY;
+ buttons[ii].buttonWidth = 53; buttons[ii].buttonHeight = BH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "Shade";
+ buttons[ii].textColor = modeColor;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Phong smooth shading and illumination */
+ ii = smooth;
+ buttons[ii].buttonX = 171; buttons[ii].buttonY = PBY;
+ buttons[ii].buttonWidth = 59; buttons[ii].buttonHeight = BH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "Smooth";
+ buttons[ii].textColor = modeColor;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Reset View Position Button */
+ ii = resetView;
+ buttons[ii].buttonX = 240; buttons[ii].buttonY = PBY;
+ buttons[ii].buttonWidth = 53; buttons[ii].buttonHeight = BH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "Reset";
+ buttons[ii].textColor = 149;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+
+ /* Second Row of Buttons */
+
+ /* update y displacement of buttons row */
+ PBY=PBY+BH+3;
+
+ /* Bounding Region On/Off */
+ ii = region3D;
+ buttons[ii].buttonX = XEDGE; buttons[ii].buttonY = PBY;
+ buttons[ii].buttonWidth = 58; buttons[ii].buttonHeight = BH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "Bounds";
+ buttons[ii].textColor = 6;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Axes Turned On/Off */
+ ii = axesOnOff;
+ buttons[ii].buttonX = 68; buttons[ii].buttonY = PBY;
+ buttons[ii].buttonWidth = 49; buttons[ii].buttonHeight = BH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "Axes";
+ buttons[ii].textColor = offColor;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Outline polygons with black lines in render mode */
+ ii = outlineOnOff;
+ buttons[ii].buttonX = 122; buttons[ii].buttonY = PBY;
+ buttons[ii].buttonWidth = 70; buttons[ii].buttonHeight = BH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "Outline";
+ buttons[ii].textColor = offColor;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Display as if a 1-bit plane image */
+ ii = bwColor;
+ buttons[ii].buttonX = 197; buttons[ii].buttonY = PBY;
+ buttons[ii].buttonWidth = 33; buttons[ii].buttonHeight = BH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "BW";
+ buttons[ii].textColor = offColor;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Hide Control Panel */
+ ii = hideControl;
+ buttons[ii].buttonX = 240; buttons[ii].buttonY = PBY;
+ buttons[ii].buttonWidth = 53; buttons[ii].buttonHeight = BH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "Hide";
+ buttons[ii].textColor = 149;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+
+ /* Third Row of Buttons */
+
+ /* update y displacement of buttons row */
+ PBY=PBY+BH+3;
+
+ /* Shows Lighting Control Panel */
+ ii = lighting;
+ buttons[ii].buttonX = XEDGE; buttons[ii].buttonY = PBY;
+ buttons[ii].buttonWidth = 65; buttons[ii].buttonHeight = BH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "Light";
+ buttons[ii].textColor = 149;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Shows View Volume Control Panel */
+ ii = viewVolume;
+ buttons[ii].buttonX = 75; buttons[ii].buttonY = PBY;
+ buttons[ii].buttonWidth = 100; buttons[ii].buttonHeight = BH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "View Volume";
+ buttons[ii].textColor = 149;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Shows Save Panel */
+ ii = saveit;
+ buttons[ii].buttonX = 180; buttons[ii].buttonY = PBY;
+ buttons[ii].buttonWidth = 50; buttons[ii].buttonHeight = BH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "Save";
+ buttons[ii].textColor = 149;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Exits from the viewport running */
+ ii = closeAll;
+ buttons[ii].buttonX = 240; buttons[ii].buttonY = PBY;
+ buttons[ii].buttonWidth = 53; buttons[ii].buttonHeight = BH;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "Quit";
+ buttons[ii].textColor = offColor;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Buttons to control potentiometers */
+ /* These buttons appear above the potentiometer windows which they affect. */
+
+ /* Rotate potentiometer buttons */
+
+ /* Rotate about the origin indicated by the axes */
+ /* Red is off, Green is on */
+ ii = originr;
+ buttons[ii].buttonX = XEDGE; buttons[ii].buttonY = 55;
+ buttons[ii].buttonWidth = 53; buttons[ii].buttonHeight = 25;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "origin";
+ buttons[ii].textColor = onColor;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Rotate about the objects center of volume */
+ /* Red is off, Green is on */
+ ii = objectr;
+ buttons[ii].buttonX = 62; buttons[ii].buttonY = 55;
+ buttons[ii].buttonWidth = 53; buttons[ii].buttonHeight = 25;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "object";
+ buttons[ii].textColor = offColor;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Scale potentiometer buttons */
+
+ /* Scale along X axis: Red is off, Green is on */
+ ii = zoomx;
+ buttons[ii].buttonX = 121; buttons[ii].buttonY = 55;
+ buttons[ii].buttonWidth = 17; buttons[ii].buttonHeight = 25;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "x";
+ buttons[ii].textColor = onColor;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Scale along Y axis: Red is off, Green is on */
+ ii = zoomy;
+ buttons[ii].buttonX = 141; buttons[ii].buttonY = 55;
+ buttons[ii].buttonWidth = 17; buttons[ii].buttonHeight = 25;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "y";
+ buttons[ii].textColor = onColor;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Zoom along Z axis: Red is off, Green is on */
+ ii = zoomz;
+ buttons[ii].buttonX = 161; buttons[ii].buttonY = 55;
+ buttons[ii].buttonWidth = 17; buttons[ii].buttonHeight = 25;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "z";
+ buttons[ii].textColor = onColor;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Translate potentiometer buttons */
+
+ /* Indicates an orthographic projection of the xy-plane,
+ translation is in x and y coordinates */
+ ii = xy;
+ buttons[ii].buttonX = 185; buttons[ii].buttonY = 55;
+ buttons[ii].buttonWidth= 34; buttons[ii].buttonHeight = 25;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "xy";
+ buttons[ii].textColor = 35;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Indicates an orthographic projection of the xz-plane,
+ translation is in x and z coordinates */
+ ii = xz;
+ buttons[ii].buttonX = 223; buttons[ii].buttonY = 55;
+ buttons[ii].buttonWidth= 34; buttons[ii].buttonHeight = 25;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "xz";
+ buttons[ii].textColor = 35;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ /* Indicates an orthographic projection of the yz-plane,
+ translation is in y and z coordinates */
+ ii = yz;
+ buttons[ii].buttonX = 261; buttons[ii].buttonY = 55;
+ buttons[ii].buttonWidth= 34; buttons[ii].buttonHeight = 25;
+ buttons[ii].buttonKey = ii;
+ buttons[ii].pot = no;
+ buttons[ii].mask = buttonMASK;
+ buttons[ii].text = "yz";
+ buttons[ii].textColor = 35;
+ buttons[ii].xHalf = buttons[ii].buttonWidth/2;
+ buttons[ii].yHalf = buttons[ii].buttonHeight/2;
+ ++num;
+
+ return(num);
+
+} /* initButtons() */
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/closeView3d.c.pamphlet b/src/graph/view3D/closeView3d.c.pamphlet
new file mode 100644
index 00000000..22ca3fbe
--- /dev/null
+++ b/src/graph/view3D/closeView3d.c.pamphlet
@@ -0,0 +1,116 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D closeView3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _CLOSEVIEW3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include <stdlib.h>
+#include "header.h"
+
+#include "util.H1"
+#include "Gfun.H1"
+#include "all_3d.H1"
+
+
+
+/*****************************************************
+ * int closeViewport() *
+ * *
+ * This closes all of the windows created for the *
+ * control panel window and the viewport window of *
+ * the current graph being displayed. *
+ * It does not currently return a specified value. *
+ * *
+ *****************************************************/
+
+void
+#ifdef _NO_PROTO
+closeViewport ()
+#else
+closeViewport (void)
+#endif
+{
+ int i;
+
+ /* First, unlink viewport from global list of viewports */
+ if (viewport->prevViewport) { /* if there is a viewport before it */
+ (viewport->prevViewport)->nextViewport = viewport->nextViewport;
+ } else { /* this is the first viewport */
+ viewport = viewport->nextViewport;
+ }
+ if (viewport->nextViewport) { /* if there is a viewport following it */
+ (viewport->nextViewport)->prevViewport = viewport->prevViewport;
+ }
+
+ /* Free up the control panel button windows */
+ for (i=0; i<maxButtons3D; i++) {
+ XDeleteAssoc(dsply,table,(control->buttonQueue[i]).self);
+ }
+
+ /* Free up the control panel window */
+ XDestroyWindow(dsply,control->controlWindow);
+ free(control);
+
+ /* Free up the viewport window */
+
+ XDestroyWindow(dsply,viewport->viewWindow);
+ XDestroyWindow(dsply,viewport->titleWindow);
+ free(viewport);
+
+ XFlush(dsply);
+
+} /* closeViewport() */
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/component3d.c.pamphlet b/src/graph/view3D/component3d.c.pamphlet
new file mode 100644
index 00000000..3b22805d
--- /dev/null
+++ b/src/graph/view3D/component3d.c.pamphlet
@@ -0,0 +1,908 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D component3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _COMPONENT3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include "header.h"
+#include "draw.h"
+
+#include "Gfun.H1"
+#include "util.H1"
+#include "XSpadFill.H1"
+
+#include "all_3d.H1"
+
+#define axisLength 1.0 /* use 100.0, if data is not to be normalized */
+
+#define samePoint(a,b) ((refPt3D(viewData,a)->x == refPt3D(viewData,b)->x) &&\
+ (refPt3D(viewData,a)->y == refPt3D(viewData,b)->y) &&\
+ (refPt3D(viewData,a)->z == refPt3D(viewData,b)->z))
+#define MAX_POINT 1000.0
+#define MIN_POINT -1000.0
+
+
+void
+#ifdef _NO_PROTO
+scaleComponents ()
+#else
+scaleComponents (void)
+#endif
+{
+
+ double xRange,yRange,zRange;
+ int i;
+ viewTriple *aPoint;
+
+ /* Temporary range limits until the three dimensional clipping
+ package is fully functional */
+
+ if (viewData.xmin < MIN_POINT) viewData.xmin = MIN_POINT;
+ if (viewData.xmax > MAX_POINT) viewData.xmax = MAX_POINT;
+ if (viewData.ymin < MIN_POINT) viewData.ymin = MIN_POINT;
+ if (viewData.ymax > MAX_POINT) viewData.ymax = MAX_POINT;
+ if (viewData.zmin < MIN_POINT) viewData.zmin = MIN_POINT;
+ if (viewData.zmax > MAX_POINT) viewData.zmax = MAX_POINT;
+
+ xRange = viewData.xmax - viewData.xmin;
+ yRange = viewData.ymax - viewData.ymin;
+ zRange = viewData.zmax - viewData.zmin;
+
+ /* We scale down, normalize the data, if it is coming from AXIOM
+ (handled by viewman). If the data is coming from a file (handled by
+ viewAlone) then it should already been scaled down.
+ */
+
+ /* Find the coordinate axis with the larges range of data and scale
+ the others relative to it.
+ */
+ /* compare x and y ranges */
+ if (xRange > yRange) {
+ if (xRange > zRange) {
+ if (absolute(viewData.xmax) >= absolute(viewData.xmin))
+ viewData.scaleToView = axisLength/(absolute(viewData.xmax));
+ else
+ viewData.scaleToView = axisLength/(absolute(viewData.xmin));
+ } else {
+ if (absolute(viewData.zmax) >= absolute(viewData.zmin))
+ viewData.scaleToView = axisLength/(absolute(viewData.zmax));
+ else
+ viewData.scaleToView = axisLength/(absolute(viewData.zmin));
+ }
+ } else {
+ if (yRange > zRange) {
+ if (absolute(viewData.ymax) >= absolute(viewData.ymin))
+ viewData.scaleToView = axisLength/(absolute(viewData.ymax));
+ else
+ viewData.scaleToView = axisLength/(absolute(viewData.ymin));
+ } else {
+ if (absolute(viewData.zmax) >= absolute(viewData.zmin))
+ viewData.scaleToView = axisLength/(absolute(viewData.zmax));
+ else
+ viewData.scaleToView = axisLength/(absolute(viewData.zmin));
+ }
+ }
+
+ /* We now normalize all the points in this program. The information
+ needed to link the normalized set of points back to the real object
+ space scale created in AXIOM is held in viewData.scaleToView. */
+ viewData.xmin *= viewData.scaleToView;
+ viewData.xmax *= viewData.scaleToView;
+ viewData.ymin *= viewData.scaleToView;
+ viewData.ymax *= viewData.scaleToView;
+ viewData.zmin *= viewData.scaleToView;
+ viewData.zmax *= viewData.scaleToView;
+ viewData.clipXmin = viewData.xmin;
+ viewData.clipXmax = viewData.xmax;
+ viewData.clipYmin = viewData.ymin;
+ viewData.clipYmax = viewData.ymax;
+ viewData.clipZmin = viewData.zmin;
+ viewData.clipZmax = viewData.zmax;
+
+ for (i=0, aPoint=viewData.points; i<viewData.numOfPoints; i++,aPoint++) {
+ aPoint->x *= viewData.scaleToView;
+ aPoint->y *= viewData.scaleToView;
+ aPoint->z *= viewData.scaleToView;
+ }
+
+} /* scaleComponents() */
+
+
+/*
+ void makeTriangle(a,b,c)
+ Given three indices to three points, a triangular polygon is created
+ and inserted into the polygon list of viewData. If two or more of the
+ points are coincidental, no polygon is created since that would be a
+ degenerate (collapsed) polygon.
+ */
+
+void
+#ifdef _NO_PROTO
+makeTriangle (a, b, c)
+ int a,b,c;
+#else
+makeTriangle (int a, int b, int c)
+#endif
+{
+ poly *aPoly;
+
+ if (!(samePoint(a,b) || samePoint(b,c) || samePoint(c,a))) {
+ /* create triangle only if the three vertex points are distinct */
+ aPoly = (poly *)saymem("component.c",1,sizeof(poly));
+ aPoly->num = aPoly->sortNum = viewData.numPolygons++;
+ aPoly->split = aPoly->moved = no;
+ aPoly->numpts = 3;
+ aPoly->primitiveType = polygonComponent;
+ aPoly->indexPtr = (int *)saymem("component.c",3,sizeof(int));
+ *(aPoly->indexPtr) = a;
+ *(aPoly->indexPtr + 1) = b;
+ *(aPoly->indexPtr + 2) = c;
+ aPoly->doNotStopDraw = yes;
+ aPoly->next = viewData.polygons;
+ viewData.polygons = aPoly;
+ } /* if all points are unique */
+
+} /* makeTriangle() */
+
+
+
+
+/*
+ void triangulate()
+
+ Only if there is more than one list do we triangulate; a single list
+ is used for either a space curve or simply a point. Actually, in that
+ case, we now make "flat" *polygons, flagged by the primitiveType field
+ (pointComponent, etc. in tube.h). We need to examine two lists at a time
+ (and if the structure is closed, the last and first as well). For every
+ three points in the two lists, alternating between one in one and two in
+ the other, we construct triangles. If one list is shorter, then its last
+ point becomes the vertex for the remaining pairs of points from the other
+ list. It turns out that any distribution of points in the two lists
+ (preserving cyclic order) will produce the same desired polygon.
+ */
+
+void
+#ifdef _NO_PROTO
+triangulate ()
+#else
+triangulate (void)
+#endif
+{
+
+ int u,l;
+ int uBound,lBound;
+ int i,j,k;
+ LLPoint *anLLPoint;
+ LPoint *list1,*list2;
+ poly *aPoly;
+
+ anLLPoint = viewData.lllp.llp;
+ for (i=0; i<viewData.lllp.numOfComponents; i++,anLLPoint++) {
+ if (anLLPoint->numOfLists > 1) {
+ list2 = anLLPoint->lp;
+ for (j=1; j<anLLPoint->numOfLists; j++) {
+ list1 = list2;
+ list2 = list1 + 1;
+ u = l = 0;
+ uBound = u+1 < list1->numOfPoints;
+ lBound = l+1 < list2->numOfPoints;
+ while (uBound || lBound) {
+ if (uBound) {
+ makeTriangle(*(list1->indices + u + 1),
+ *(list1->indices + u), *(list2->indices + l));
+ u++;
+ uBound = u+1 < list1->numOfPoints;
+ }
+ if (lBound) {
+ makeTriangle(*(list2->indices + l),
+ *(list2->indices + l + 1), *(list1->indices + u));
+ l++;
+ lBound = l+1 < list2->numOfPoints;
+ }
+ } /* while (uBound || lBound) */
+ } /* for j<anLLPoint->numOfLists */
+ } /* if anLLPoint->numOfLists > 1 */
+ else {
+ /* if anLLPoint->numOfLists <= 1...assume this means =1 */
+ /* Flat polygons are to be drawn when hidden
+ surface algorithm is used.*/
+ if (anLLPoint->numOfLists == 1) {
+ if (anLLPoint->lp->numOfPoints == 1) {
+ /* this graph is a single point */
+ aPoly = (poly *)saymem("component.c",1,sizeof(poly));
+ aPoly->num = aPoly->sortNum = viewData.numPolygons++;
+ aPoly->split = aPoly->moved = no;
+ aPoly->primitiveType = pointComponent;
+ aPoly->numpts = 1;
+ aPoly->indexPtr = (int *)saymem("component.c",1,intSize);
+ *(aPoly->indexPtr) = *(anLLPoint->lp->indices);
+ aPoly->doNotStopDraw = yes;
+ aPoly->next = viewData.polygons;
+ viewData.polygons = aPoly;
+ } else {
+ /* this graph is a curve */
+ for (k=0; k<anLLPoint->lp->numOfPoints-1; k++) {
+ aPoly = (poly *)saymem("component.c",1,sizeof(poly));
+ aPoly->num = aPoly->sortNum = viewData.numPolygons++;
+ aPoly->split = aPoly->moved = no;
+ aPoly->primitiveType = lineComponent; /* curveComponent */
+ aPoly->numpts = 2;
+ aPoly->indexPtr =
+ (int *)saymem("component.c",2,sizeof(int));
+ *(aPoly->indexPtr) = *(anLLPoint->lp->indices + k);
+ *(aPoly->indexPtr+1) = *(anLLPoint->lp->indices + k + 1);
+ aPoly->doNotStopDraw = yes;
+ aPoly->next = viewData.polygons;
+ viewData.polygons = aPoly;
+ } /* for k */
+ if (anLLPoint->lp->prop.closed) {
+ aPoly = (poly *)saymem("component.c",1,sizeof(poly));
+ aPoly->num = aPoly->sortNum = viewData.numPolygons++;
+ aPoly->split = aPoly->moved = no;
+ aPoly->primitiveType = lineComponent; /* curveComponent */
+ aPoly->numpts = 2;
+ aPoly->indexPtr =
+ (int *)saymem("component.c",2,sizeof(int));
+ *(aPoly->indexPtr) = *(anLLPoint->lp->indices + k);
+ *(aPoly->indexPtr+1) = *(anLLPoint->lp->indices);
+ aPoly->doNotStopDraw = yes;
+ aPoly->next = viewData.polygons;
+ viewData.polygons = aPoly;
+ } /* if list of points is closed */
+ } /* else */
+ } /* point, line, polygon, surface components are taken care of above */
+ } /* else anLLPoint->numOfLists <= 1 */
+ } /* for LLPoints in LLLPoints (i) */
+
+} /* triangulate */
+
+
+
+void
+#ifdef _NO_PROTO
+readComponentsFromViewman ()
+#else
+readComponentsFromViewman (void)
+#endif
+{
+ int i,j,k;
+ LLPoint *anLLPoint;
+ LPoint *anLPoint;
+ viewTriple *aPoint;
+ /* maxLength holds the max(llp,lp) figure regarding how large to
+ make the array of XPoints, i.e. quadMesh, for use in calling XDraw(). */
+ int maxLength=0;
+
+ int *anIndex;
+
+ readViewman(&(viewData.numOfPoints),intSize);
+ aPoint = viewData.points =
+ (viewTriple *)saymem("component.c",viewData.numOfPoints,
+ sizeof(viewTriple));
+ for (i=0; i<viewData.numOfPoints; i++, aPoint++) {
+ readViewman(&(aPoint->x),floatSize);
+ readViewman(&(aPoint->y),floatSize);
+ readViewman(&(aPoint->z),floatSize);
+ readViewman(&(aPoint->c),floatSize);
+#ifdef NANQ_DEBUG
+ if (!(aPoint->z < 0) && !(aPoint->z > 0) && !(aPoint->z == 0))
+ fprintf(stderr,"%g\n", aPoint->z);
+#endif
+ }
+
+ readViewman(&(viewData.lllp.numOfComponents),intSize);
+ anLLPoint = viewData.lllp.llp =
+ (LLPoint *)saymem("component.c, i",viewData.lllp.numOfComponents,
+ sizeof(LLPoint));
+ for (i=0; i<viewData.lllp.numOfComponents; i++,anLLPoint++) {
+ readViewman(&(anLLPoint->prop.closed),intSize);
+ readViewman(&(anLLPoint->prop.solid),intSize);
+ readViewman(&(anLLPoint->numOfLists),intSize);
+ anLPoint = anLLPoint->lp =
+ (LPoint *)saymem("component.c, ii",anLLPoint->numOfLists,
+ sizeof(LPoint));
+ for (j=0; j<anLLPoint->numOfLists; j++,anLPoint++) {
+ if (anLLPoint->numOfLists > maxLength)
+ maxLength = anLLPoint->numOfLists;
+ readViewman(&(anLPoint->prop.closed),intSize);
+ readViewman(&(anLPoint->prop.solid),intSize);
+ readViewman(&(anLPoint->numOfPoints),intSize);
+ anIndex = anLPoint->indices =
+ (int *)saymem("component.c, index",anLPoint->numOfPoints,intSize);
+ if (anLPoint->numOfPoints > maxLength)
+ maxLength = anLPoint->numOfPoints;
+ for (k=0; k<anLPoint->numOfPoints; k++,anIndex++) {
+ readViewman(anIndex,intSize);
+ /* AXIOM arrays are one based, C arrays are zero based */
+ if (!viewAloned) (*anIndex)--;
+ }
+ } /* for LPoints in LLPoints (j) */
+ } /* for LLPoints in LLLPoints (i) */
+
+ quadMesh = (XPoint *)saymem("component.c",maxLength+2,sizeof(XPoint));
+
+} /* readComponentsFromViewman() */
+
+
+
+/*
+ void calcNormData() *
+ Calculates the surface normals for the polygons that make up the tube.
+ Also finds the fourth coefficient to the plane equation:
+ Ax + By + Cz + D = 0
+ A,B, and C are in the normal N[3] and D is the planeConst.
+ Figures out the color as well (from the average of the points) and
+ resets the moved flag
+ */
+
+void
+#ifdef _NO_PROTO
+calcNormData ()
+#else
+calcNormData (void)
+#endif
+{
+
+ poly *aPoly;
+ int *index;
+
+ for (aPoly = viewData.polygons; aPoly != NIL(poly); aPoly = aPoly->next) {
+ index = aPoly->indexPtr;
+ switch (aPoly->primitiveType) {
+ case pointComponent:
+ case lineComponent:
+ aPoly->moved = 0;
+ aPoly->color = refPt3D(viewData,*index)->c;
+ break;
+ default:
+ /*
+ The following line takes 3 consecutive points and asks
+ for the normal vector defined by them. This assumes that
+ these do not contain co-linear points. For some reason,
+ co-linear points are allowed, this needs to be changed.
+ */
+ getMeshNormal(refPt3D(viewData,*index)->x,
+ refPt3D(viewData,*index)->y,
+ refPt3D(viewData,*index)->z,
+ refPt3D(viewData,*(index+1))->x,
+ refPt3D(viewData,*(index+1))->y,
+ refPt3D(viewData,*(index+1))->z,
+ refPt3D(viewData,*(index+2))->x,
+ refPt3D(viewData,*(index+2))->y,
+ refPt3D(viewData,*(index+2))->z, 0.0, 1.0, aPoly->N);
+
+ /* calculate the constant term, D, for the plane equation */
+ aPoly->planeConst =
+ -(aPoly->N[0] * refPt3D(viewData,*index)->x +
+ aPoly->N[1] * refPt3D(viewData,*index)->y +
+ aPoly->N[2] * refPt3D(viewData,*index)->z);
+ aPoly->moved = 0;
+ aPoly->color = (refPt3D(viewData,*index)->c +
+ (refPt3D(viewData,*(index+1)))->c +
+ (refPt3D(viewData,*(index+2)))->c) / 3.0;
+ break;
+ } /* switch */
+ }
+
+} /* calcNormData() */
+
+
+
+/*
+ viewPoints *make3DComponents()
+
+ Read in all the 3D data from the viewport manager and construct the
+ model of it. The model is based upon a list of lists of lists of points.
+ Each top level list makes a component in 3-space. The interpretation
+ really begins at the level below that, where the list of lists of
+ points is. For 3D explicit equations of two variables, the closed
+ boolean for this level is False and the closed boolean for each sublist
+ is False as well. For 3D parameterized curves of one variable, the
+ closed boolean for this level is defined by the user from AXIOM ,
+ (which defaults to False) and the closed boolean for each sublist is True.
+ */
+
+viewPoints *
+#ifdef _NO_PROTO
+make3DComponents ()
+#else
+make3DComponents (void)
+#endif
+{
+ viewPoints *graphData;
+
+ readComponentsFromViewman();
+
+ /* The initial boundaries for the clipping region are set to those
+ of the boundaries of the data region. */
+ viewData.clipXmin = viewData.xmin; viewData.clipXmax = viewData.xmax;
+ viewData.clipYmin = viewData.ymin; viewData.clipYmax = viewData.ymax;
+ viewData.clipZmin = viewData.zmin; viewData.clipZmax = viewData.zmax;
+
+ /* normalize the data coordinates */
+ if (viewData.scaleDown) scaleComponents();
+ viewData.numPolygons = 0;
+ /* initially the list of polygons is empty */
+ viewData.polygons = NIL(poly);
+ /* create the polygons; (sets viewData.polygons and viewData.numPolygons) */
+ triangulate();
+ /* calculate the plane equations for all the polygons */
+ calcNormData();
+
+ graphData = makeViewport();
+
+ imageX = XCreateImage(/* display */ dsply,
+ /* visual */ DefaultVisual(dsply,scrn),
+ /* depth */ DefaultDepth(dsply,scrn),
+ /* format */ ZPixmap,
+ /* offset */ 0,
+ /* data */ NULL,
+ /* width */ vwInfo.width,
+ /* height */ 1,
+ /* bitmap_pad */ 32,
+ /* bytes_per_line */ 0);
+ imageX->data = NIL(char);
+
+ /* windowing displaying */
+ writeTitle();
+ postMakeViewport();
+ drawViewport(Xoption);
+ firstTime = yes;
+ XMapWindow(dsply, graphData->viewWindow);
+ XMapWindow(dsply, graphData->titleWindow);
+ XFlush(dsply);
+
+ return(graphData);
+
+} /* make3DComponents */
+
+
+
+
+
+void
+#ifdef _NO_PROTO
+draw3DComponents (dFlag)
+ int dFlag;
+#else
+draw3DComponents (int dFlag)
+#endif
+{
+
+ int i, j, k, hue, x1, y1, x2, y2;
+ LLPoint *anLLPoint;
+ LPoint *anLPoint;
+ int *anIndex;
+ int componentType; /* what the component is to be interpreted as */
+ int clip_a,clip_i; /* for use in wire mesh mode clipping */
+ XEvent peekEvent;
+ viewTriple *aLPt;
+ XPoint line[2];
+ RGB col_rgb;
+
+ calcEyePoint();
+ while ((XPending(dsply) > 0) && (scanline > 0))
+ XNextEvent(dsply,&peekEvent);
+ switch (viewData.style) {
+
+ case transparent:
+ GSetLineAttributes(componentGC,0,LineSolid,CapButt,JoinMiter,dFlag);
+ if (dFlag==Xoption) {
+ if (mono || viewport->monoOn)
+ GSetForeground(componentGC, (float)foregroundColor, dFlag);
+ else
+ GSetForeground(componentGC, (float) meshOutline, dFlag);
+ } else {
+ GSetForeground(componentGC, psBlack, dFlag);
+ }
+ /* no need to check "keep drawing" for ps */
+ if (dFlag == Xoption) drawMore = keepDrawingViewport();
+
+ /*
+ This is where we interpret the list of lists of lists of points struct.
+ We want to extract the following forms of data:
+ - individual points (drawn as filled points)
+ - lines (space curves)
+ - defined polygon primitives
+ - surfaces
+ the last one is the one that will replace the function of 2 variables,
+ tubes as well as 3D parameterized functions of 2 variables.
+ Since there could be many other ways of constructing L L L Pts - much
+ more than could be usefully interpreted - any other formats are
+ currently not allowed. When they are, this comment should be updated
+ appropriately.
+
+ ************************************************************************
+
+ Traverse each component.
+ We decide here, before we begin traversing the
+ component what we want to interpret it as.
+ Here's the convention used to figure that out:
+ - points: #anLLPoint->numOfLists was 1
+ #anLPoint->numOfPoints is 1
+ - lines: #anLLPoint->numOfLists was 1
+ #anLPoint->numOfPoints > 1
+ - polygons: #anLLPoint->numOfLists was 2
+ #anLPoint->numOfPoints is 1
+ - surface: #anLLPoint->numOfLists was some m>1
+ #anLPoint->numOfPoints all point lists are the same.
+
+ */
+
+ anLLPoint = viewData.lllp.llp;
+ for (i=0; i<viewData.lllp.numOfComponents; i++,anLLPoint++) {
+ /* initially, component type is unknown */
+ componentType = stillDontKnow;
+ if (anLLPoint->numOfLists == 1) {
+ if (anLLPoint->lp->numOfPoints == 1) componentType = pointComponent;
+ else componentType = lineComponent;
+ } else if (anLLPoint->numOfLists == 2) {
+ if ((anLLPoint->lp->numOfPoints == 1) &&
+ ((anLLPoint->lp+1)->numOfPoints > 2))
+ componentType = polygonComponent;
+ }
+ /* Check for corrupt data and NaN data is made in AXIOM . */
+ if (componentType == stillDontKnow)
+ componentType = surfaceComponent;
+
+ anLPoint = anLLPoint->lp;
+
+ switch (componentType) {
+
+ case pointComponent:
+ /* anLLPoint->numOfLists == anLLPoint->lp->numOfPoints == 1 here */
+ aLPt = refPt3D(viewData,*(anLPoint->indices));
+ project(aLPt,quadMesh,0);
+ if (dFlag==Xoption) {
+ if (mono || viewport->monoOn)
+ GSetForeground(componentGC, (float)foregroundColor, dFlag);
+ else {
+ hue = hueValue(aLPt->c);
+ GSetForeground(componentGC, (float)XSolidColor(hue,2), dFlag);
+ }
+ } else GSetForeground(componentGC, psBlack, dFlag);
+ GFillArc(componentGC,viewport->viewWindow,quadMesh->x,quadMesh->y,
+ viewData.pointSize,viewData.pointSize,0,360*64,dFlag);
+ break;
+
+ case lineComponent:
+ /* anLLPoint->numOfLists == 1 here */
+ anIndex = anLPoint->indices;
+ aLPt = refPt3D(viewData,*anIndex);
+ project(aLPt,quadMesh,0);
+ x1 = quadMesh[0].x; y1 = quadMesh[0].y; anIndex++;
+ for (k=1; k<anLPoint->numOfPoints; k++,anIndex++) {
+ aLPt = refPt3D(viewData,*anIndex);
+ project(aLPt,quadMesh,k);
+ x2 = quadMesh[k].x; y2 = quadMesh[k].y;
+ if (dFlag==Xoption) {
+ if (mono || viewport->monoOn)
+ GSetForeground(componentGC, (float)foregroundColor, dFlag);
+ else {
+ hue = hueValue(aLPt->c);
+ GSetForeground(componentGC, (float)XSolidColor(hue,2), dFlag);
+ }
+ if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
+ GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
+ } else {
+ if (dFlag==PSoption && !mono && !viewport->monoOn) {
+ hue = getHue(aLPt->c);
+ col_rgb = hlsTOrgb((float)hue,0.5,0.8);
+ line[0].x = x1; line[0].y = y1;
+ line[1].x = x2; line[1].y = y2;
+ PSDrawColor(col_rgb.r,col_rgb.g,col_rgb.b,line,2);
+ } else {
+ if (foregroundColor == white)
+ GSetForeground(componentGC, 0.0, dFlag);
+ else
+ GSetForeground(componentGC, psBlack, dFlag);
+ if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
+ GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
+ }
+ }
+ x1 = x2; y1 = y2;
+ } /* for points in LPoints (k) */
+ if (anLPoint->prop.closed) {
+ project(refPt3D(viewData,*(anLPoint->indices)),quadMesh,
+ anLPoint->numOfPoints);
+ x2 = quadMesh[anLPoint->numOfPoints].x;
+ y2 = quadMesh[anLPoint->numOfPoints].y;
+ if (dFlag==Xoption) {
+ if (mono || viewport->monoOn)
+ GSetForeground(componentGC, (float)foregroundColor, dFlag);
+ else {
+ hue = hueValue(aLPt->c);
+ GSetForeground(componentGC, (float)XSolidColor(hue,2), dFlag);
+ }
+ if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
+ GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
+ }
+ else {
+ if (dFlag==PSoption && !mono && !viewport->monoOn) {
+ hue = getHue(aLPt->c);
+ col_rgb = hlsTOrgb((float)hue,0.5,0.8);
+ line[0].x = x1; line[0].y = y1;
+ line[1].x = x2; line[1].y = y2;
+ PSDrawColor(col_rgb.r,col_rgb.g,col_rgb.b,line,2);
+ }
+ else {
+ if (foregroundColor == white)
+ GSetForeground(componentGC, 0.0, dFlag);
+ else
+ GSetForeground(componentGC, psBlack, dFlag);
+ if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
+ GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
+ }
+ }
+ }
+ break;
+
+ case polygonComponent:
+ /* first pt of polygon is a single list */
+ project(refPt3D(viewData,*(anLPoint->indices)),quadMesh,0);
+ /* remaining points in the 2nd list (always of size 2 or greater) */
+ x1 = quadMesh[0].x; y1 = quadMesh[0].y;
+ anLPoint = anLLPoint->lp + 1;
+ anIndex = anLPoint->indices;
+ for (k=1; k<=anLPoint->numOfPoints; k++,anIndex++) {
+ aLPt = refPt3D(viewData,*anIndex);
+ project(aLPt,quadMesh,k);
+ x2 = quadMesh[k].x; y2 = quadMesh[k].y;
+ if (dFlag==Xoption) {
+ if (mono || viewport->monoOn)
+ GSetForeground(componentGC, (float)foregroundColor, dFlag);
+ else {
+ hue = hueValue(aLPt->c);
+ GSetForeground(componentGC, (float)XSolidColor(hue,2), dFlag);
+ }
+ if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
+ GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
+ }
+ else {
+ if (dFlag==PSoption && !mono && !viewport->monoOn) {
+ hue = getHue(aLPt->c);
+ col_rgb = hlsTOrgb((float)hue,0.5,0.8);
+ line[0].x = x1; line[0].y = y1;
+ line[1].x = x2; line[1].y = y2;
+ PSDrawColor(col_rgb.r,col_rgb.g,col_rgb.b,line,2);
+ }
+ else {
+ if (foregroundColor == white)
+ GSetForeground(componentGC, 0.0, dFlag);
+ else
+ GSetForeground(componentGC, psBlack, dFlag);
+ if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
+ GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
+ }
+ }
+ x1 = x2; y1 = y2;
+ } /* for points in LPoints (k) */
+ project(refPt3D(viewData,*(anLLPoint->lp->indices)),quadMesh,k);
+ x2 = quadMesh[k].x; y2 = quadMesh[k].y;
+ if (dFlag==Xoption) {
+ if (mono || viewport->monoOn)
+ GSetForeground(componentGC, (float)foregroundColor, dFlag);
+ else {
+ hue = hueValue(refPt3D(viewData,*anIndex)->c);
+ GSetForeground(componentGC, (float)XSolidColor(hue,2), dFlag);
+ }
+ if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
+ GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
+ } else {
+ if (dFlag==PSoption && !mono && !viewport->monoOn) {
+ hue = getHue(refPt3D(viewData,*anIndex)->c);
+ col_rgb = hlsTOrgb((float)hue,0.5,0.8);
+ line[0].x = x1; line[0].y = y1;
+ line[1].x = x2; line[1].y = y2;
+ PSDrawColor(col_rgb.r,col_rgb.g,col_rgb.b,line,2);
+ }
+ else {
+ if (foregroundColor == white)
+ GSetForeground(componentGC, 0.0, dFlag);
+ else
+ GSetForeground(componentGC, psBlack, dFlag);
+ if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
+ GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
+ }
+ }
+ /* close a polygon */
+ break;
+
+ case surfaceComponent:
+ if (dFlag==Xoption) {
+ if (mono || viewport->monoOn)
+ GSetForeground(componentGC, (float)foregroundColor, dFlag);
+ else
+ GSetForeground(componentGC, (float) meshOutline, dFlag);
+ }
+ else {
+ GSetForeground(componentGC, psBlack, dFlag);
+ }
+
+ /* traverse down one direction first (all points
+ in a list at a time) */
+ for (j=0; drawMore && j<anLLPoint->numOfLists; j++,anLPoint++) {
+ anIndex = anLPoint->indices;
+ clip_a = 0;
+ for (k=0, clip_i=0;
+ drawMore && k<anLPoint->numOfPoints;
+ k++, anIndex++, clip_i++) {
+ aLPt = refPt3D(viewData,*anIndex);
+ project(aLPt,quadMesh,k);
+
+ if (behindClipPlane(aLPt->pz) ||
+ (viewData.clipStuff &&
+ outsideClippedBoundary(aLPt->x, aLPt->y, aLPt->z))) {
+ if (clip_i - clip_a > 1) {
+ GDrawLines(componentGC,viewport->viewWindow,(quadMesh+clip_a),
+ clip_i-clip_a, CoordModeOrigin, dFlag );
+ }
+ clip_a = clip_i + 1;
+ }
+
+ drawMore = keepDrawingViewport();
+ } /* for points in LPoints (k) */
+ if (drawMore) {
+ /* if drawMore is true, then the above loop terminated with
+ clip_i incremented properly */
+ if (anLPoint->prop.closed) {
+ /* If closed, then do the first point again - no need to project
+ just copy over from the first one */
+ aLPt = refPt3D(viewData,*(anLPoint->indices));
+ project(aLPt,quadMesh, anLPoint->numOfPoints);
+ if (behindClipPlane(aLPt->pz) ||
+ (viewData.clipStuff &&
+ outsideClippedBoundary(aLPt->x, aLPt->y, aLPt->z))) {
+ if (clip_i - clip_a > 1) {
+ GDrawLines(componentGC, viewport->viewWindow,
+ (quadMesh+clip_a), clip_i-clip_a,
+ CoordModeOrigin, dFlag);
+ }
+ clip_a = clip_i + 1;
+ }
+ clip_i++;
+ } /* closed */
+ if (clip_i - clip_a > 1) {
+ GDrawLines(componentGC, viewport->viewWindow, (quadMesh+clip_a),
+ clip_i-clip_a, CoordModeOrigin, dFlag);
+ }
+ } /* drawMore */
+ } /* for LPoints in LLPoints (j) */
+
+ /* now traverse down the list in the other direction
+ (one point from each list at a time) */
+ for (j=0; drawMore && j<anLLPoint->lp->numOfPoints; j++) {
+ clip_a = 0;
+ for (k=0, clip_i=0;
+ drawMore && k<anLLPoint->numOfLists;
+ k++, clip_i++) {
+ aLPt = refPt3D(viewData,*((anLLPoint->lp + k)->indices + j));
+ project(aLPt, quadMesh,k);
+
+ if (behindClipPlane(aLPt->pz) ||
+ (viewData.clipStuff &&
+ outsideClippedBoundary(aLPt->x, aLPt->y, aLPt->z))) {
+ if (clip_i - clip_a > 1) {
+ GDrawLines(componentGC,viewport->viewWindow,quadMesh+clip_a,
+ clip_i-clip_a, CoordModeOrigin, dFlag );
+ }
+ clip_a = clip_i + 1;
+ }
+ drawMore = keepDrawingViewport();
+ } /* for points in LPoints (k) */
+
+ if (drawMore) {
+ /* if drawMore is true, then the above loop terminated with
+ clip_i incremented properly */
+ if (anLLPoint->prop.closed) {
+ /* if closed, do the first point again - no need to project
+ just copy over from the first one */
+ aLPt = refPt3D(viewData,*((anLLPoint->lp + 0)->indices + j));
+ project(aLPt, quadMesh, anLLPoint->numOfLists);
+ if (behindClipPlane(aLPt->pz) ||
+ (viewData.clipStuff &&
+ outsideClippedBoundary(aLPt->x, aLPt->y, aLPt->z))) {
+ if (clip_i - clip_a > 1) {
+ GDrawLines(componentGC, viewport->viewWindow,
+ quadMesh + clip_a, clip_i - clip_a,
+ CoordModeOrigin, dFlag);
+ }
+ clip_a = clip_i + 1;
+ }
+ clip_i++;
+ } /* closed */
+ if (clip_i - clip_a > 1) {
+ GDrawLines(componentGC, viewport->viewWindow, quadMesh+clip_a,
+ clip_i-clip_a, CoordModeOrigin, dFlag);
+ }
+ } /* drawMore */
+ } /* for a point in each LPoint (j) */
+ break;
+ } /* switch componentType */
+ } /* for LLPoints in LLLPoints (i) */
+ break;
+
+ case opaqueMesh:
+ if (dFlag==Xoption) {
+ GSetForeground(globGC, (float)opaqueForeground, dFlag);
+ GSetForeground(opaqueGC, (float)opaqueOutline, dFlag);
+ }
+ else {
+ GSetForeground(globGC, psBlack, dFlag);
+ GSetForeground(opaqueGC, psBlack, dFlag);
+ }
+ GSetLineAttributes(opaqueGC,0,LineSolid,CapButt,JoinRound,dFlag);
+ drawPolygons(dFlag);
+ break;
+
+ case render:
+ if (viewData.outlineRenderOn) {
+ GSetLineAttributes(renderGC,0,LineSolid,CapButt,JoinRound,dFlag);
+ if (dFlag==Xoption) GSetForeground(renderGC,(float)black, dFlag);
+ else GSetForeground(renderGC,psBlack, dFlag );
+ }
+ drawPolygons(dFlag);
+ break;
+
+ case smooth:
+ drawPhong(dFlag);
+ break;
+
+ } /* switch on style */
+
+} /* draw3DComponents() */
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/contour.h b/src/graph/view3D/contour.h
new file mode 100755
index 00000000..d037c442
--- /dev/null
+++ b/src/graph/view3D/contour.h
@@ -0,0 +1,195 @@
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+
+
+ /***********************************************************************
+ contour.h
+ ***********************************************************************/
+#define segDEBUG
+
+/* #define contour -100*/
+
+#define CONTOUR_float double
+#define ACTIVE_poly_struct poly
+
+#define line_crosses_plane(z_min, z_max, z_val) \
+ ((z_min < z_val) && (z_max >= z_val))
+
+#ifdef oldie
+typedef struct _active_poly_struct {
+ struct _active_poly_struct *next;
+ int num;
+ struct _poly *polygon;
+} active_poly_struct;
+#endif
+
+typedef struct _segment_struct {
+ struct _segment_struct *next;
+ struct _viewTriple *point1, *point2;
+} segment_struct;
+
+typedef struct _segment_list_struct {
+ int num_segs;
+ segment_struct *segments;
+ int num, max_num; /* num=slice num, max_num=#slices for this contour */
+} segment_list_struct;
+
+ /*=====================================================================*
+ Macro Definitions
+ *=====================================================================*/
+#define foreach_slice(index, slice, slice_list, max_slices) \
+ for (index=0; \
+ (index<max_slices) && (int)(slice=(slice_list+index)); \
+ index++)
+#define foreach_segment(seg, slice, fl) \
+ for (seg=slice->segments; (fl) && (seg != NIL(segment_struct)); seg=seg->next)
+
+#define foreach_segment_old(idx, s, sl, max, fl) \
+ for (idx=0; idx<max; idx++) \
+ for (s=(sl+idx)->segments; (fl) && (s != NIL(segment_struct)); s=s->next)
+
+ /*---------------------------------------------------------------------*
+ interface stuff
+ *---------------------------------------------------------------------*/
+#ifdef oldie
+#define contourCursorForeground moColor(red1, light)
+#define contourCursorBackground moColor(green0, normal)
+#else
+#define contourCursorForeground monoColor(68)
+#define contourCursorBackground monoColor(197)
+#endif
+
+#define contourMASK ExposureMask
+
+#define contourPlaneTextCOLOR 28
+
+ /*---------------------------------------------------*
+ title, dividing lines & stuff
+ *---------------------------------------------------*/
+#define contourTitleColor moColor(blue0, normal)
+#define contourTitleA 190
+#define contourTitleB 217
+
+#define dotSize 8
+#define dotExt 12
+#define dotColor moColor(red2, pastel)
+
+ /*---------------------------------------------------*
+ Button Positions & Dimensions
+ *---------------------------------------------------*/
+#define contourPlaneXY_X 150
+#define contourPlaneXY_Y 250
+#define contourPlaneXZ_X 190
+#define contourPlaneXZ_Y 250
+#define contourPlaneYZ_X 230
+#define contourPlaneYZ_Y 250
+#define contourLittleButt_W 20
+#define contourLittleButt_H 20
+
+#define contourFlatView_X 120
+#define contourFlatView_Y 290
+#define contourAppendSegs_X 120
+#define contourAppendSegs_Y 320
+#ifdef oldie
+#define contourBigButt_W 170
+#define contourBigButt_H 20
+#else
+#define contourBigButt_W 10
+#define contourBigButt_H 10
+#endif
+ /*---------------------------------------------------*
+ Line & button colors
+ *---------------------------------------------------*/
+#define abort_FG moColor(red1, pastel)
+#define return_FG moColor(green2, pastel)
+#define littleButt_FG moColor(yellow0, pastel)
+#define bigButt_FG moColor(orange1, pastel)
+
+ /*---------------------------------------------------*
+ longitude part
+ *---------------------------------------------------*/
+#define contourLongitude_X 10
+#define contourLongitude_Y 55
+#define contourLongitude_W 135
+#define contourLongitude_H 120
+
+#define long_FG moColor(green1, normal)
+#define long_corner_X 36
+#define long_corner_Y 72
+#define long_RADIUS 40
+#define long_W (long_RADIUS<<1)
+#define long_H (long_RADIUS<<1)
+
+#define long_center_X (long_corner_X + long_RADIUS)
+#define long_center_Y (long_corner_Y + long_RADIUS)
+
+#define long_str_X 15
+#define long_str_Y 48
+
+ /*---------------------------------------------------*
+ latitude part
+ *---------------------------------------------------*/
+#define contourLatitude_X 160
+#define contourLatitude_Y 55
+#define contourLatitude_W 135
+#define contourLatitude_H 120
+
+#define lat_FG moColor(green1, normal)
+#define lat_corner_X 130
+#define lat_corner_Y 85
+#define lat_RADIUS 60
+#define lat_W (lat_RADIUS<<1)
+#define lat_H (lat_RADIUS<<1)
+#define lat_quad_X (lat_corner_X + lat_RADIUS)
+#define lat_quad_Y (lat_corner_Y + lat_RADIUS)
+
+#define lat_str_X 176
+#define lat_str_Y 48
+
+ /*---------------------------------------------------*
+ slice part
+ *---------------------------------------------------*/
+#define contourSliceNum_X 10
+#define contourSliceNum_Y 245
+#define contourSliceNum_W 90
+#define contourSliceNum_H 115
+
+#define slice_FG moColor(red1, normal)
+
+#define slice_str_X 20
+#define slice_str_Y 240
+#define slicer_image_X 50
+#define slicer_image_Y 253
+
+#define MAX_SLICES 100
+
diff --git a/src/graph/view3D/contour3d.c.out b/src/graph/view3D/contour3d.c.out
new file mode 100755
index 00000000..14e791e2
--- /dev/null
+++ b/src/graph/view3D/contour3d.c.out
@@ -0,0 +1,675 @@
+ /***********************************************************************
+ contour.c
+
+ begun 19 September 1992, Jim Wen
+ ***********************************************************************/
+
+#include "header.h"
+#include "draw.h"
+
+#define segmentDEBUG_X
+
+#define contourDEBUG_X
+#define use_min
+#define realloc_bug_fixed_NOT
+
+ /*=====================================================================*
+ Static variables
+ *=====================================================================*/
+int noo=0;
+poly *contour_poly_list;
+poly *active_list_first, *active_list_last, *active_list_current;
+segment_list_struct *tmp_segment_list;
+
+ /*=====================================================================*
+ macro definitions
+ *=====================================================================*/
+#define foreach_poly(p) for ((p)=contour_poly_list; p != NIL(poly); p=p->next)
+#define foreach_active(p,f,l) if (f != NIL(poly)) for (p=f; p!=l; p=(p)->next)
+#define in_range(x,a,b) ( ((x>=a) && (x<b)) || ((x<a) && (x>=b)) )
+#define poly_in_plane(p,z) ( (p->contour_min==z) && (p->contour_max==z) )
+
+
+
+ /*=====================================================================*
+ local function declarations
+ *=====================================================================*/
+int contour_compare();
+void add_segment();
+segment_struct *make_the_segment();
+viewTriple *mkpoint();
+CONTOUR_float get_t_from_pts();
+void make_active_list();
+int maintain_active_list();
+void contour_minMaxPolygons();
+
+ /*=====================================================================*
+ contour_compare()
+
+ The compare function passed to msort.
+ *=====================================================================*/
+int contour_compare(p1,p2)
+ poly *p1, *p2;
+{
+
+#ifdef use_min
+ if (p1->contour_min < p2->contour_min) return(-1);
+ else if (p1->contour_min == p2->contour_min) return(0);
+ else return(1);
+#else
+ if (p1->contour_max > p2->contour_max) return(-1);
+ else if (p1->contour_max == p2->contour_max) return(0);
+ else return(1);
+#endif /* use_min */
+} /* contour_compare() */
+
+ /*=====================================================================*
+ do_contour_map()
+ *=====================================================================*/
+int do_contour_map()
+{
+
+ poly *pp;
+ poly *ap;
+ CONTOUR_float z_now;
+ int got_more;
+ int *anIndex;
+ viewTriple *aPt, *daPt, *one_point;
+ int jj, segment_index;
+ int got_one_intersection;
+ int done;
+ segment_list_struct *sl;
+#ifdef contour_object_rotate
+ float rotMat[4][4];
+ float transformed_zmax, transformed_zmin;
+#endif
+#ifdef conDEBUG
+ segment_struct *seg;
+#endif
+
+ /*---------------------------------------------------*
+ the flag "did_contour" should be set to "no" whenever
+ the user modifies one of the parameters
+ *---------------------------------------------------*/
+#ifdef contourDEBUG_x
+ fprintf(stderr,"Contour is %s\n",(did_contour)?"yes":"no");
+#endif
+ if (did_contour) return 1;
+ did_contour = yes;
+
+#ifdef contour_object_rotate
+ /*---------------------------------------------------*
+ transform all the points for arbitrary plane
+ slicing. this includes all the viewTriples
+ being referenced as well as the boundaries
+ in viewData (to get contour_min, contour_max).
+ *---------------------------------------------------*/
+#ifdef oldie
+ rot_theta = 0;
+ rot_phi = pi/2;
+#endif
+
+ sinTheta = sin(-rot_theta);
+ cosTheta = cos(-rot_theta);
+ sinPhi = sin(rot_phi);
+ cosPhi = cos(rot_phi);
+ ROTATE1(rotMat);
+
+ /*---------------------------------------------------*
+ transform all the points.
+ the zmin and zmax values need to be recalculated
+ now that the object has been transformed. note
+ that transforming the z extreme points will not
+ work correctly (i know, i've tried it).
+ *---------------------------------------------------*/
+ {
+ int i,j,k;
+ LLPoint *anLLPoint;
+ LPoint *anLPoint;
+ int *anIndex;
+ viewTriple *daPoint;
+ float v_in[4], v_out[4];
+ int first_time = yes;
+
+ anLLPoint = viewData.lllp.llp;
+ for (i=0; i<viewData.lllp.numOfComponents; i++,anLLPoint++) {
+ anLPoint = anLLPoint->lp;
+ for (j=0; j<anLLPoint->numOfLists; j++,anLPoint++) {
+ anIndex = anLPoint->indices;
+ for (k=0; k<anLPoint->numOfPoints; k++,anIndex++) {
+ daPoint = refPt3D(viewData, *anIndex);
+ /*---------------------------------------------------*
+ inefficient code so that the vector package could
+ be used to see if things work;
+ should change viewTriple's <x,y,z> to an array(?)
+ *---------------------------------------------------*/
+ v_in[0] = daPoint->x; v_in[1] = daPoint->y;
+ v_in[2] = daPoint->z; v_in[3] = 1.0;
+ vectorMatrix4(v_in, rotMat, v_out);
+ daPoint->contour_x = v_out[0];
+ daPoint->contour_y = v_out[1];
+ daPoint->contour_z = v_out[2];
+ if (first_time) {
+ first_time = no;
+ transformed_zmin = transformed_zmax = v_out[2];
+ } else {
+ if (v_out[2] < transformed_zmin)
+ transformed_zmin = v_out[2];
+ else if (v_out[2] > transformed_zmax)
+ transformed_zmax = v_out[2];
+ }
+ } /* for points in LPoints (k) */
+ } /* for LPoints in LLPoints (j) */
+ } /* for LLPoints in LLLPoints (i) */
+
+ }
+
+#endif
+
+
+ /*---------------------------------------------------*
+ set up the step size - it should be user adjustable
+ and include all the slices possible.
+ max_cuts is #slices seen
+ z_step is #slices made
+ cuts_used is #slices actually displayed
+ *---------------------------------------------------*/
+ z_step = (transformed_zmax - transformed_zmin)/max_cuts;
+#ifdef oldie
+ cuts_used = max_cuts;
+#endif
+
+ /*---------------------------------------------------*
+ calculate the bounds of the polygons - the
+ contour_minMaxPolygons routine looks at the
+ contour points rather than the object or
+ projected points
+ *---------------------------------------------------*/
+ contour_poly_list = copyPolygons(viewData.polygons);
+ contour_minMaxPolygons(contour_poly_list);
+
+ /*---------------------------------------------------*
+ sort the polygons by the zmax value
+ (or whatever transformed value, in general)
+ *---------------------------------------------------*/
+ contour_poly_list = msort(contour_poly_list, 0,
+ viewData.numPolygons, contour_compare);
+
+ /*---------------------------------------------------*
+ having figured out how many cuts we need (should
+ be a one time overhead so the following stuff
+ should be in the initialization routine), we
+ allocate an array of segment lists and initialize
+ them (this part can stay here).
+ *---------------------------------------------------*/
+#ifdef oldie
+ segment_list = saymem("contour.c: segment_list",
+ max_cuts, sizeof(segment_list_struct));
+#else
+ /*---------------------------------------------------*
+ if the append flag is set, then we want to add
+ the new segment stuff onto the end of the old
+ stuff (to build up a model of the surface).
+ tmp_segment_list is use to keep track of the
+ head of the new list while the routine goes
+ through its paces.
+ *---------------------------------------------------*/
+ if (contour_append_lists_flag) {
+ noo = 0;
+#ifdef segmentDEBUG
+ fprintf(stderr,"======= series %d ========\n",noo);
+ fprintf(stderr," ---> before: sl->num=%d [%x]\n",
+ segment_list->num, segment_list);
+#endif
+
+#ifdef realloc_bug_fixed
+ realloc(segment_list, (cuts_used + max_cuts) * sizeof(segment_list_struct));
+ tmp_segment_list = segment_list;
+ segment_list += cuts_used; /* shift to end of list */
+ cuts_used += max_cuts; /* size of new list */
+
+#ifdef segmentDEBUG
+ fprintf(stderr,"> %d cuts => seg at %x [old=%x]\n",
+ cuts_used, segment_list, tmp_segment_list);
+ fprintf(stderr," sl->num=%d, tsl->num=%d\n",
+ segment_list->num, tmp_segment_list->num);
+#endif
+
+#else /* DONT_WORK */
+
+ /*---------------------------------------------------*
+ Because realloc doesn't seem to work properly,
+ we need to do this by hand
+ *---------------------------------------------------*/
+ /*---------------------------------------------------*
+ allocate new space
+ *---------------------------------------------------*/
+ tmp_segment_list = saymem("contour.c: segment_list, append",
+ cuts_used + max_cuts,
+ sizeof(segment_list_struct));
+
+ /*---------------------------------------------------*
+ copy over old data (1..cuts_used)
+ *---------------------------------------------------*/
+ {
+ segment_list_struct *tsl;
+
+ for (segment_index=0, sl=segment_list, tsl=tmp_segment_list;
+ segment_index<cuts_used;
+ segment_index++, sl++, tsl++) {
+ tsl->num = sl->num;
+ tsl->max_num = sl->max_num;
+ tsl->num_segs = sl->num_segs;
+ tsl->segments = sl->segments;
+ }
+ }
+
+ /*---------------------------------------------------*
+ free the old stuff
+ *---------------------------------------------------*/
+/* free(segment_list); */
+
+ /*---------------------------------------------------*
+ now set segment_list to point to the point
+ where tmp_segment_list stops - there ought
+ to me max_cuts storage spaces left.
+ *---------------------------------------------------*/
+ segment_list = tmp_segment_list + cuts_used;
+
+ /*---------------------------------------------------*
+ update cuts_used to have everything for a possible
+ next iteration
+ *---------------------------------------------------*/
+ cuts_used += max_cuts;
+
+#endif /* realloc_BUG */
+
+
+ } else {
+ if (contour_allocated) {
+/* free(segment_list); */
+ } else {
+ contour_allocated = yes;
+ }
+ noo = 0;
+ segment_list = saymem("contour.c: segment_list",
+ max_cuts, sizeof(segment_list_struct));
+ cuts_used = max_cuts;
+#ifdef segmentDEBUG
+ fprintf(stderr,"======= series %d ========\n",noo);
+ fprintf(stderr,"%d cuts => seg at %x\n",cuts_used, segment_list);
+#endif
+ }
+#endif
+
+ for (segment_index=0, sl=segment_list;
+ segment_index<max_cuts;
+ segment_index++, sl++) {
+ sl->num = ++noo;
+ sl->max_num = max_cuts;
+#ifdef segmentDEBUG
+ fprintf(stderr,"Made segment list %d [%x]\n",noo,sl);
+/* fprintf(stderr," ...(tsl->num=%d [%x]\n",
+ tmp_segment_list->num, tmp_segment_list); */
+#endif
+ sl->num_segs = 0;
+ sl->segments = NIL(segment_struct);
+ }
+ /*---------------------------------------------------*
+ create an "active_list" of polygons such that
+ this slice step intersects all and only those
+ polygons in the active list.
+ *---------------------------------------------------*/
+ make_active_list(contour_poly_list,
+#ifdef use_min
+ transformed_zmin, transformed_zmin+z_step,
+#else
+ transformed_zmax, transformed_zmax-z_step,
+#endif
+ &active_list_first, &active_list_last, &active_list_current);
+
+ /*---------------------------------------------------*
+ iterate from zmax down to zmin with z_step increments
+ *---------------------------------------------------*/
+ segment_index = 0;
+#ifdef use_min
+ for (z_now=transformed_zmin; z_now<transformed_zmax; /* see below for incr*/) {
+#else
+ for (z_now=transformed_zmax; z_now>transformed_zmin; /* see below for incr*/) {
+#endif
+ /*---------------------------------------------------*
+ for each of the polygons on the active list,
+ intersect each of line equation for the sides
+ with the plane equation for the plane at z_now.
+ one of the following may occur:
+ no intersections: haha - can't happen coz active
+ one intersection : at the point, create point line
+ two intersections: create line connecting points
+ lies in the plane: create three segments
+ note that this is a fairly inefficient approach but
+ i'm just throwing this stuff together in an afternoon
+ to see how it looks
+ *---------------------------------------------------*/
+ foreach_active(ap, active_list_first, active_list_last) {
+
+ /*---------------------------------------------------*
+ do line-plane equation for each side of the
+ polygon
+ for now - just 3+ sided polygons (no degenerates)
+ *---------------------------------------------------*/
+
+ if (ap->numpts >= 3) {
+ if (poly_in_plane(ap, z_now)) {
+ /*---------------------------------------------------*
+ re-create all the segments of the polygon
+ *---------------------------------------------------*/
+ daPt = refPt3D(viewData, *(ap->indexPtr + (ap->numpts - 1)));
+ for (jj=0, anIndex=ap->indexPtr; jj<ap->numpts; jj++, anIndex++) {
+ aPt = refPt3D(viewData, *anIndex);
+ add_segment(segment_list, segment_index,
+ make_the_segment(aPt, daPt));
+ daPt = aPt;
+ }
+ } else {
+ /*---------------------------------------------------*
+ find the line that defines the intersection of
+ the polygon with the z-plane
+ *---------------------------------------------------*/
+ got_one_intersection = no;
+ done = no;
+ daPt = refPt3D(viewData, *(ap->indexPtr + (ap->numpts - 1)));
+ for (jj=0, anIndex=ap->indexPtr;
+ !done && jj<ap->numpts;
+ jj++, anIndex++) {
+ aPt = refPt3D(viewData, *anIndex);
+ if (in_range(z_now, aPt->contour_z, daPt->contour_z)) {
+ if (got_one_intersection) {
+ add_segment(segment_list, segment_index,
+ make_the_segment(one_point,
+ mkpoint(aPt, daPt, z_now)));
+ done = yes;
+ } else {
+ one_point = mkpoint(aPt, daPt, z_now);
+ got_one_intersection = yes;
+ }
+ }
+ daPt = aPt;
+ } /* for */
+ } /* else not lie in plane */
+
+ }
+ } /* foreach_active(ap) */
+
+ /*---------------------------------------------------*
+ maintain/update the active list, pruning off things
+ the fall off the top (beyond z_now - z_step) and
+===> adding on things to the bottom that now fall into
+ the range [z_now ---> z_now-z_step].
+ *---------------------------------------------------*/
+ segment_index++;
+#ifdef use_min
+ z_now += z_step;
+ got_more = maintain_active_list(&active_list_first,
+ &active_list_last,
+ &active_list_current,
+ z_now + z_step,
+ z_now);
+#else
+ z_now -= z_step;
+ got_more = maintain_active_list(&active_list_first,
+ &active_list_last,
+ &active_list_current,
+ z_now,
+ z_now - z_step);
+#endif
+ } /* for z_now from zmax to zmin */
+
+ /*---------------------------------------------------*
+ if the segment lists have been appended, reset
+ the global segment lists pointer to the top of
+ the lists
+ *---------------------------------------------------*/
+ if (contour_append_lists_flag) {
+ segment_list = tmp_segment_list;
+#ifdef segmentDEBUG
+#ifdef oldie
+ fprintf(stderr," setting seg to old=%x\n", segment_list);
+ fprintf(stderr," num is %d\n",segment_list->num);
+#endif
+ {
+
+ for (segment_index=0, sl=segment_list;
+ segment_index<cuts_used;
+ segment_index++, sl++) {
+ fprintf(stderr," sl->num = %d\n",sl->num);
+ }
+ }
+
+#endif
+ }
+
+} /* do_contour_map() */
+
+
+ /*=====================================================================*
+ make_active_list(da_list, z_min, z_max, af, al, ac)
+ *=====================================================================*/
+void make_active_list(da_list, z_min, z_max, af, al, ac)
+ poly *da_list;
+ CONTOUR_float z_min, z_max;
+ poly **af, **al, **ac;
+{
+
+ poly *tmp_p;
+
+ /*---------------------------------------------------*
+ the first active polygon is the first one in the
+ given, sorted list. note that if it doesn't fall
+===> inside the z_max --> z_min range, af is set to NIL.
+ *---------------------------------------------------*/
+#ifdef use_min
+ if (da_list->contour_min > z_max) {
+#else
+ if (da_list->contour_max < z_min) {
+#endif
+ *af = NIL(poly);
+ return;
+ } else {
+ *af = da_list;
+ }
+
+ /*---------------------------------------------------*
+ the current active polygon is set to "af" at this
+ point but it could be the case that it is set to
+ "al" if, for example, the current span of z-values
+ has no polygons - af is set to NIL, and the next
+ time we look we start at ac=af.
+ *---------------------------------------------------*/
+ *ac = *af;
+
+ /*---------------------------------------------------*
+ the last active polygon is the polygon right before
+===> the first one whose zmax is too small to make the
+ list
+ *---------------------------------------------------*/
+ *al = da_list;
+ tmp_p = da_list->next;
+ for (; tmp_p != NIL(poly); tmp_p = tmp_p->next) {
+#ifdef use_min
+ if (tmp_p->contour_min > z_max) return;
+#else
+ if (tmp_p->contour_max < z_min) return;
+#endif
+ *al = tmp_p;
+ }
+
+} /* make_active_list() */
+
+
+ /*=====================================================================*
+ maintain_active_list(af, al, ac, z_max, z_min)
+ *=====================================================================*/
+int maintain_active_list(af, al, ac, z_max, z_min)
+ poly **al, **af, **ac;
+ CONTOUR_float z_max, z_min;
+{
+
+ poly *tmp_p;
+
+ /*---------------------------------------------------*
+ first, get the lower boundary to be within range,
+ pruning elements from the head of the list
+ *---------------------------------------------------*/
+ *af = *ac;
+#ifdef use_min
+ while ((*af) && (*af)->contour_max < z_min) {
+#else
+ while ((*af) && (*af)->contour_min > z_max) {
+#endif
+ *af = (*af)->next;
+ }
+
+ /*---------------------------------------------------*
+ check to see if the upper boundary is still in
+ range
+ *---------------------------------------------------*/
+#ifdef use_min
+ if ((*af) == NIL(poly) || ((*af)->contour_min > z_max)) {
+#else
+ if ((*af) == NIL(poly) || ((*af)->contour_max < z_min)) {
+#endif
+ /* --- nope, it wasn't --- */
+ *ac = *af;
+ *af = NIL(poly);
+ return(0);
+ }
+
+ /*---------------------------------------------------*
+ upper boundary is okay...see if we need to add to
+ the list on the lower bound side
+ *---------------------------------------------------*/
+ tmp_p = (*al)->next;
+ for (; tmp_p != NIL(poly); tmp_p = tmp_p->next) {
+#ifdef use_min
+ if (tmp_p->contour_min > z_max) return;
+#else
+ if (tmp_p->contour_max < z_min) return;
+#endif
+ *al = tmp_p;
+ }
+
+ return(1);
+
+} /* maintain_active_list() */
+
+
+ /*=====================================================================*
+ add_segment(seg_list, index, seg)
+ *=====================================================================*/
+void add_segment(seg_list, index, seg)
+ segment_list_struct *seg_list;
+ int index;
+ segment_struct *seg;
+{
+
+ segment_list_struct *sl;
+
+ sl = seg_list + index;
+
+ seg->next = sl->segments;
+ sl->segments = seg;
+ sl->num_segs++;
+
+} /* add_segment() */
+
+
+ /*=====================================================================*
+ make_the_segment(pt1, pt2)
+ *=====================================================================*/
+segment_struct *make_the_segment(pt1, pt2)
+ viewTriple *pt1, *pt2;
+{
+ segment_struct *seg;
+
+ seg = (segment_struct *)saymem("contour.c: segment",1,sizeof(segment_struct));
+ seg->point1 = pt1;
+ seg->point2 = pt2;
+
+ return(seg);
+
+} /* make_the_segment() */
+
+
+ /*=====================================================================*
+ viewTriple *mkpoint(vt1, vt2, z_val)
+ *=====================================================================*/
+viewTriple *mkpoint(vt1, vt2, z_val)
+ viewTriple *vt1, *vt2;
+ CONTOUR_float z_val;
+{
+
+ viewTriple *vt;
+ CONTOUR_float t;
+
+ vt = (viewTriple *)saymem("contour.c: viewTriple",1,sizeof(viewTriple));
+
+ t = get_t_from_pts(vt1->contour_z, vt2->contour_z, z_val);
+
+#ifdef waitaminute
+ vt->x = vt1->contour_x + (vt2->contour_x - vt1->contour_x) * t;
+ vt->y = vt1->contour_y + (vt2->contour_y - vt1->contour_y) * t;
+ vt->z = z_val;
+#else
+ vt->x = vt1->x + (vt2->x - vt1->x) * t;
+ vt->y = vt1->y + (vt2->y - vt1->y) * t;
+ vt->z = vt1->z + (vt2->z - vt1->z) * t;
+#endif
+
+ vt->contour_x = vt1->contour_x + (vt2->contour_x - vt1->contour_x) * t;
+ vt->contour_y = vt1->contour_y + (vt2->contour_y - vt1->contour_y) * t;
+ vt->contour_z = z_val;
+
+ return(vt);
+
+} /* mkpoint() */
+
+
+
+ /*=====================================================================*
+ get_t_from_pts(z_min, z_max, z_val)
+ *=====================================================================*/
+CONTOUR_float get_t_from_pts(z_min, z_max, z_val)
+ CONTOUR_float z_min, z_max, z_val;
+{
+ CONTOUR_float t;
+
+ if (z_min == z_max) return 0;
+
+ t = (z_val - z_min)/(z_max - z_min);
+
+ return(t);
+} /* get_t_from_pts() */
+
+
+void contour_minMaxPolygons(aPoly)
+ poly *aPoly;
+{
+
+ int *anIndex;
+ int i;
+
+
+ for (; aPoly != NIL(poly); aPoly = aPoly->next) {
+ anIndex = aPoly->indexPtr;
+ aPoly->contour_min = aPoly->contour_max =
+ refPt3D(viewData,*anIndex)->contour_z;
+ for (i=1,anIndex++; i<aPoly->numpts; i++,anIndex++) {
+ if (refPt3D(viewData,*anIndex)->contour_z < aPoly->contour_min)
+ aPoly->contour_min = refPt3D(viewData,*anIndex)->contour_z;
+ else if (refPt3D(viewData,*anIndex)->contour_z > aPoly->contour_max)
+ aPoly->contour_max = refPt3D(viewData,*anIndex)->contour_z;
+ }
+ }
+
+
+} /* contour_minMaxPolygons */
diff --git a/src/graph/view3D/contour_panel3d.c.out b/src/graph/view3D/contour_panel3d.c.out
new file mode 100755
index 00000000..45709849
--- /dev/null
+++ b/src/graph/view3D/contour_panel3d.c.out
@@ -0,0 +1,760 @@
+ /***********************************************************************
+ contour_panel.c
+
+ begun 25 November 1992, Jim Wen
+ ***********************************************************************/
+
+#include "header.h"
+#include "cpanel.h"
+#include "draw.h"
+#include "../include/purty/volume.bitmap"
+#include "../include/purty/volume.mask"
+#include "../include/purty/slicer.bitmap"
+
+#define use_fat
+
+#define gStuff_NOT
+
+#define contourWinDEBUG
+#define drawDEBUG
+#define contourDEBUG
+
+#define stickColor moColor(orange2, pastel)
+
+ /*=====================================================================*
+ Static Variables
+ *=====================================================================*/
+XImage slicer_image_stuff, *slicer_image = &slicer_image_stuff;
+int last_tip_long_x, last_tip_long_y;
+int last_tip_lat_x, last_tip_lat_y;
+
+ /*=====================================================================*
+ Local Functions
+ *=====================================================================*/
+int initContourButtons();
+
+ /*---------------------------------------------------------------------*
+ makeContourPanel()
+ *---------------------------------------------------------------------*/
+int makeContourPanel()
+{
+
+ int i;
+ XSetWindowAttributes cwAttrib, controlAttrib;
+ XSizeHints sizehint;
+ Pixmap contourbits, contourmask, slicer_pixmap;
+ XColor foreColor, backColor;
+
+ contourbits = XCreateBitmapFromData(dsply,rtWindow,volumeBitmap_bits,
+ volumeBitmap_width,volumeBitmap_height);
+ contourmask = XCreateBitmapFromData(dsply,rtWindow,volumeMask_bits,
+ volumeMask_width,volumeMask_height);
+ cwAttrib.background_pixel = backgroundColor;
+ cwAttrib.border_pixel = foregroundColor;
+ cwAttrib.event_mask = contourMASK;
+ cwAttrib.colormap = colorMap;
+ cwAttrib.override_redirect = overrideManager;
+ foreColor.pixel = contourCursorForeground;
+ XQueryColor(dsply,colorMap,&foreColor);
+ backColor.pixel = contourCursorBackground;
+ XQueryColor(dsply,colorMap,&backColor);
+ cwAttrib.cursor = XCreatePixmapCursor(dsply,contourbits,contourmask,
+ &foreColor,&backColor,
+ volumeBitmap_x_hot,
+ volumeBitmap_y_hot);
+
+#define slicer_pixmap_FG moColor(yellow1,normal)
+#define slicer_pixmap_BG backgroundColor
+ slicer_pixmap = XCreatePixmapFromBitmapData(dsply, control->controlWindow,
+ slicer_bits, slicer_width, slicer_height,
+ slicer_pixmap_FG, slicer_pixmap_BG,
+ DefaultDepthOfScreen
+ (DefaultScreenOfDisplay(dsply)));
+ slicer_image = XGetImage(dsply, slicer_pixmap, 0, 0, slicer_width, slicer_height,
+ AllPlanes, ZPixmap);
+
+
+ contourWindow = XCreateWindow(dsply,control->controlWindow,
+ -3,-3,controlWidth,controlHeight,3,
+ CopyFromParent,InputOutput,CopyFromParent,
+ controlCreateMASK,&cwAttrib);
+
+ sizehint.flags = USPosition | USSize;
+ sizehint.x = 0;
+ sizehint.y = 0;
+ sizehint.width = controlWidth;
+ sizehint.height = controlHeight;
+ /*** the None stands for icon pixmap ***/
+ XSetNormalHints(dsply,contourWindow,&sizehint);
+ XSetStandardProperties(dsply,contourWindow,"Control Panel 3D",
+ "Contour Slicing",None,NULL,0,&sizehint);
+
+ /*** volume frustrum window ***/
+
+ /*** do contour buttons ***/
+ initContourButtons(control->buttonQueue);
+ for (i=contourButtonsStart; i<(contourButtonsEnd); i++) {
+ controlAttrib.event_mask = (control->buttonQueue[i]).mask;
+ (control->buttonQueue[i]).self =
+ XCreateWindow(dsply,contourWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,
+ 0,0,InputOnly,CopyFromParent,
+ buttonCreateMASK,&controlAttrib);
+ XMakeAssoc(dsply,table,(control->buttonQueue[i]).self,
+ &((control->buttonQueue[i]).buttonKey));
+ XMapWindow(dsply,(control->buttonQueue[i]).self);
+ }
+
+} /* makeContourPanel() */
+
+
+int initContourButtons(contourButtons)
+
+buttonStruct *contourButtons;
+{
+
+ int ii, num = 0;
+
+ ii = contourReturn;
+ contourButtons[ii].buttonX = 154;
+ contourButtons[ii].buttonY = 370;
+ contourButtons[ii].buttonWidth = 110;
+ contourButtons[ii].buttonHeight = 24;
+ contourButtons[ii].buttonKey = ii;
+ contourButtons[ii].pot = no;
+ contourButtons[ii].mask = buttonMASK;
+ contourButtons[ii].text = "Return";
+ contourButtons[ii].textColor = return_FG;
+ contourButtons[ii].xHalf = contourButtons[ii].buttonWidth/2;
+ contourButtons[ii].yHalf = contourButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = contourXY;
+ contourButtons[ii].buttonX = contourPlaneXY_X;
+ contourButtons[ii].buttonY = contourPlaneXY_Y;
+ contourButtons[ii].buttonWidth = contourLittleButt_W;
+ contourButtons[ii].buttonHeight = contourLittleButt_H;
+ contourButtons[ii].buttonKey = ii;
+ contourButtons[ii].pot = no;
+ contourButtons[ii].mask = buttonMASK;
+ contourButtons[ii].text = "XY";
+ contourButtons[ii].textColor = littleButt_FG;
+ contourButtons[ii].xHalf = contourButtons[ii].buttonWidth/2;
+ contourButtons[ii].yHalf = contourButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = contourXZ;
+ contourButtons[ii].buttonX = contourPlaneXZ_X;
+ contourButtons[ii].buttonY = contourPlaneXZ_Y;
+ contourButtons[ii].buttonWidth = contourLittleButt_W;
+ contourButtons[ii].buttonHeight = contourLittleButt_H;
+ contourButtons[ii].buttonKey = ii;
+ contourButtons[ii].pot = no;
+ contourButtons[ii].mask = buttonMASK;
+ contourButtons[ii].text = "XZ";
+ contourButtons[ii].textColor = littleButt_FG;
+ contourButtons[ii].xHalf = contourButtons[ii].buttonWidth/2;
+ contourButtons[ii].yHalf = contourButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = contourYZ;
+ contourButtons[ii].buttonX = contourPlaneYZ_X;
+ contourButtons[ii].buttonY = contourPlaneYZ_Y;
+ contourButtons[ii].buttonWidth = contourLittleButt_W;
+ contourButtons[ii].buttonHeight = contourLittleButt_H;
+ contourButtons[ii].buttonKey = ii;
+ contourButtons[ii].pot = no;
+ contourButtons[ii].mask = buttonMASK;
+ contourButtons[ii].text = "YZ";
+ contourButtons[ii].textColor = littleButt_FG;
+ contourButtons[ii].xHalf = contourButtons[ii].buttonWidth/2;
+ contourButtons[ii].yHalf = contourButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = contourFlatView;
+ contourButtons[ii].buttonX = contourFlatView_X;
+ contourButtons[ii].buttonY = contourFlatView_Y;
+ contourButtons[ii].buttonWidth = contourBigButt_W;
+ contourButtons[ii].buttonHeight = contourBigButt_H;
+ contourButtons[ii].buttonKey = ii;
+ contourButtons[ii].pot = no;
+ contourButtons[ii].mask = potMASK;
+ contourButtons[ii].text = "Flat View Upon Return";
+ contourButtons[ii].textColor = bigButt_FG;
+ contourButtons[ii].xHalf = contourButtons[ii].buttonWidth/2;
+ contourButtons[ii].yHalf = contourButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = contourAppendSegs;
+ contourButtons[ii].buttonX = contourAppendSegs_X;
+ contourButtons[ii].buttonY = contourAppendSegs_Y;
+ contourButtons[ii].buttonWidth = contourBigButt_W;
+ contourButtons[ii].buttonHeight = contourBigButt_H;
+ contourButtons[ii].buttonKey = ii;
+ contourButtons[ii].pot = no;
+ contourButtons[ii].mask = potMASK;
+ contourButtons[ii].text = "Append Contours";
+ contourButtons[ii].textColor = bigButt_FG;
+ contourButtons[ii].xHalf = contourButtons[ii].buttonWidth/2;
+ contourButtons[ii].yHalf = contourButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = contourLongitude;
+ contourButtons[ii].buttonX = contourLongitude_X;
+ contourButtons[ii].buttonY = contourLongitude_Y;
+ contourButtons[ii].buttonWidth = contourLongitude_W;
+ contourButtons[ii].buttonHeight = contourLongitude_H;
+ contourButtons[ii].buttonKey = ii;
+ contourButtons[ii].pot = yes;
+ contourButtons[ii].mask = potMASK;
+ contourButtons[ii].text = "XZ";
+ contourButtons[ii].textColor = long_FG;
+ contourButtons[ii].xHalf = contourButtons[ii].buttonWidth/2;
+ contourButtons[ii].yHalf = contourButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = contourLatitude;
+ contourButtons[ii].buttonX = contourLatitude_X;
+ contourButtons[ii].buttonY = contourLatitude_Y;
+ contourButtons[ii].buttonWidth = contourLatitude_W;
+ contourButtons[ii].buttonHeight = contourLatitude_H;
+ contourButtons[ii].buttonKey = ii;
+ contourButtons[ii].pot = yes;
+ contourButtons[ii].mask = potMASK;
+ contourButtons[ii].text = "XZ";
+ contourButtons[ii].textColor = lat_FG;
+ contourButtons[ii].xHalf = contourButtons[ii].buttonWidth/2;
+ contourButtons[ii].yHalf = contourButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = contourSliceNum;
+ contourButtons[ii].buttonX = contourSliceNum_X;
+ contourButtons[ii].buttonY = contourSliceNum_Y;
+ contourButtons[ii].buttonWidth = contourSliceNum_W;
+ contourButtons[ii].buttonHeight = contourSliceNum_H;
+ contourButtons[ii].buttonKey = ii;
+ contourButtons[ii].pot = yes;
+ contourButtons[ii].mask = potMASK;
+ contourButtons[ii].text = "XZ";
+ contourButtons[ii].textColor = slice_FG;
+ contourButtons[ii].xHalf = contourButtons[ii].buttonWidth/2;
+ contourButtons[ii].yHalf = contourButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = contourAbort;
+ contourButtons[ii].buttonX = 36;
+ contourButtons[ii].buttonY = 370;
+ contourButtons[ii].buttonWidth = 110;
+ contourButtons[ii].buttonHeight = 24;
+ contourButtons[ii].buttonKey = ii;
+ contourButtons[ii].pot = no;
+ contourButtons[ii].mask = buttonMASK;
+ contourButtons[ii].text = "Abort";
+ contourButtons[ii].textColor = abort_FG;
+ contourButtons[ii].xHalf = contourButtons[ii].buttonWidth/2;
+ contourButtons[ii].yHalf = contourButtons[ii].buttonHeight/2;
+ ++num;
+
+
+ return(num);
+
+} /* initContourButtons() */
+
+
+void drawContourPanel()
+{
+
+ int i,strlength;
+
+ /*---------------------------------------------------*
+ Set the function to copy for first painting
+ *---------------------------------------------------*/
+ XSetFunction(dsply, contourGC, GXcopy);
+
+ /* Draw some lines for the contour panel, break up da space */
+ GSetForeground(contourGC /* ZZZ */,(float)foregroundColor,X);
+ GSetLineAttributes(contourGC /* ZZZ */,3,LineSolid,CapButt,JoinMiter,X);
+ GDrawLine(contourGC /* ZZZ */, contourWindow, 0, potA, controlWidth, potA, X);
+
+
+ GSetLineAttributes(contourGC /* ZZZ */,2,LineSolid,CapButt,JoinMiter,X);
+ GDrawLine(contourGC /* ZZZ */, contourWindow, 0, contourTitleA, controlWidth,
+ contourTitleA, X);
+ GDrawLine(contourGC /* ZZZ */, contourWindow, 0, contourTitleB, controlWidth,
+ contourTitleB, X);
+
+ writeControlTitle(contourWindow);
+ s = "Contour Slicing Panel";
+ strlength = strlen(s);
+ GSetForeground(anotherGC,(float)contourTitleColor,X);
+ GDrawString(anotherGC,contourWindow,
+ centerX(anotherGC,s,strlength,controlWidth),
+ contourTitleA+18,s,strlength,X);
+
+ for (i=contourButtonsStart; i<(contourButtonsEnd); i++) {
+ /*---------------------------------------------------*
+ NOTE: different from other control panels in that
+ the "monoColor" is defined in the button
+ and "moColor" is used there
+ *---------------------------------------------------*/
+ GSetForeground(contourGC /* ZZZ */,
+#ifdef oldie
+ (float)monoColor((control->buttonQueue[i]).textColor),X);
+#else
+ (float)((control->buttonQueue[i]).textColor),X);
+#endif
+ switch (i) {
+
+ case contourFlatView:
+ case contourAppendSegs:
+ GSetForeground(contourGC,
+ (float)((control->buttonQueue[i]).textColor),X);
+ GDrawRectangle(contourGC,contourWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,X);
+ GDrawString(contourGC,contourWindow,
+ (control->buttonQueue[i]).buttonX +
+ (control->buttonQueue[i]).buttonWidth + 4,
+ (control->buttonQueue[i]).buttonY +
+ centerY(contourGC,(control->buttonQueue[i]).buttonHeight),
+ (control->buttonQueue[i]).text,
+ strlen(control->buttonQueue[i].text),X);
+ if (i==contourFlatView && contour_flat_view_flag)
+ GDrawString(contourGC,contourWindow,
+ (control->buttonQueue[i]).buttonX +
+ centerX(contourGC,"x",1,
+ (control->buttonQueue[i]).buttonWidth),
+ (control->buttonQueue[i]).buttonY +
+ centerY(contourGC,(control->buttonQueue[i]).buttonHeight),
+ "x",1,X);
+ else if (i==contourAppendSegs && contour_append_lists_flag)
+ GDrawString(contourGC,contourWindow,
+ (control->buttonQueue[i]).buttonX +
+ centerX(contourGC,"x",1,
+ (control->buttonQueue[i]).buttonWidth),
+ (control->buttonQueue[i]).buttonY +
+ centerY(contourGC,(control->buttonQueue[i]).buttonHeight),
+ "x",1,X);
+ break;
+
+ case contourLongitude:
+ GDrawRectangle(contourGC /* ZZZ */,contourWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,X);
+ draw_contour_longitude();
+ break;
+
+ case contourLatitude:
+#ifdef oldie
+ GDrawRectangle(contourGC /* ZZZ */,contourWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,X);
+#else
+ XDrawRectangle(dsply,contourWindow, contourGC /* ZZZ */,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight);
+#endif
+ draw_contour_latitude();
+ break;
+
+ case contourSliceNum:
+ GDrawRectangle(contourGC /* ZZZ */,contourWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,X);
+ draw_contour_slicing();
+ break;
+
+ default:
+ GDrawRectangle(contourGC /* ZZZ */,contourWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,X);
+ s = (control->buttonQueue[i]).text;
+ strlength = strlen(s);
+ GSetForeground(contourGC /* ZZZ */,
+#ifdef oldie
+ (float)monoColor((control->buttonQueue[i]).textColor),X);
+#else
+ (float)((control->buttonQueue[i]).textColor),X);
+#endif
+ GDrawString(trashGC /* ZZZ */,contourWindow,
+ (control->buttonQueue[i]).buttonX +
+ centerX(processGC,s,strlength,
+ (control->buttonQueue[i]).buttonWidth),
+ (control->buttonQueue[i]).buttonY +
+ centerY(processGC,(control->buttonQueue[i]).buttonHeight),
+ s,strlen(s),X);
+ break;
+ } /* switch on i */
+ } /* for contour buttons */
+
+ /*---------------------------------------------------*
+ Set the function to XOR for updating
+ *---------------------------------------------------*/
+ XSetFunction(dsply, contourGC, GXxor);
+ update_contour_longitude(); /* to get the xor stuff going */
+ update_contour_latitude(); /* to get the xor stuff going */
+
+} /* drawContourPanel() */
+
+
+ /*---------------------------------------------------------------------*
+ draw_contour_longitude()
+ *---------------------------------------------------------------------*/
+void draw_contour_longitude()
+{
+
+ int tip_x, tip_y;
+ char stringo[20];
+
+
+ /*---------------------------------------------------*
+ print out the longitude in degrees
+ *---------------------------------------------------*/
+ sprintf(stringo,"Longitude: %d",(int)(rot_theta * DEGREES));
+ XClearArea(dsply, contourWindow, long_str_X, long_str_Y - 12,
+ long_W + 50, 18, False);
+ XDrawString(dsply, contourWindow, anotherGC,
+ long_str_X, long_str_Y,
+ stringo, strlen(stringo));
+
+ /*---------------------------------------------------*
+ draw the background artwork
+ *---------------------------------------------------*/
+ XClearArea(dsply, contourWindow,
+ contourLongitude_X, contourLongitude_Y,
+ contourLongitude_W, contourLongitude_H,
+ False);
+#ifdef use_fat
+ XSetForeground(dsply, contourGC /* ZZZ */, long_FG);
+ XDrawArc(dsply, contourWindow, contourGC /* ZZZ */,
+ long_corner_X, long_corner_Y,
+ long_W, long_H,
+ 0, 360*64);
+#else
+ XSetForeground(dsply, contourGC, long_FG);
+ XSetForeground(dsply, trashGC, long_FG);
+ XDrawArc(dsply, contourWindow, trashGC /* ZZZ */,
+ long_corner_X, long_corner_Y,
+ long_W, long_H,
+ 0, 360*64);
+#endif
+
+ /*---------------------------------------------------*
+ some spokes to make it look purty
+ *---------------------------------------------------*/
+ {
+ float a, xp, yp;
+ for (a=0; a<pi; a+=pi/8) {
+ xp = long_RADIUS*cos(a);
+ yp = long_RADIUS*sin(a);
+ XDrawLine(dsply, contourWindow,
+#ifdef use_fat
+ contourGC,
+#else
+ trashGC,
+#endif
+ (int)(xp + long_center_X), (int)(yp + long_center_Y),
+ (int)(-xp + long_center_X), (int)(-yp + long_center_Y));
+ }
+ }
+
+ /*---------------------------------------------------*
+ calculate and draw the longitudal pointer
+ *---------------------------------------------------*/
+ XSetFunction(dsply, contourGC, GXxor);
+ tip_x = (int)(cos(rot_theta) * (long_RADIUS + dotExt)) + long_center_X;
+ tip_y = (int)(-sin(rot_theta) * (long_RADIUS + dotExt)) + long_center_Y;
+ last_tip_long_x = tip_x;
+ last_tip_long_y = tip_y;
+ GSetForeground(contourGC,(float)stickColor,X);
+ GDrawLine(contourGC /* ZZZ */, contourWindow,
+ long_center_X, long_center_Y,
+ tip_x, tip_y, X);
+ GSetForeground(contourGC,(float)dotColor,X);
+ XFillArc(dsply, contourWindow, contourGC /* ZZZ */,
+ tip_x - (dotSize>>1), tip_y - (dotSize>>1),
+ dotSize, dotSize,
+ 0, 360*64);
+ XSetFunction(dsply, contourGC, GXcopy);
+
+} /* draw_contour_longitude() */
+
+
+ /*---------------------------------------------------------------------*
+ draw_contour_latitude()
+ *---------------------------------------------------------------------*/
+void draw_contour_latitude()
+{
+
+ int tip_x, tip_y;
+ char stringo[20];
+
+ /*---------------------------------------------------*
+ print out the latitude in degrees
+ *---------------------------------------------------*/
+ sprintf(stringo,"Latitude: %d",(int)(rot_phi * DEGREES));
+ XClearArea(dsply, contourWindow, lat_str_X, lat_str_Y - 12,
+ lat_W, 18, False);
+ XDrawString(dsply, contourWindow, anotherGC,
+ lat_str_X, lat_str_Y,
+ stringo, strlen(stringo));
+
+ /*---------------------------------------------------*
+ draw the background superduper work of art
+ *---------------------------------------------------*/
+ XClearArea(dsply, contourWindow,
+ contourLatitude_X, contourLatitude_Y,
+ contourLatitude_W, contourLatitude_H,
+ False);
+ XSetForeground(dsply, contourGC /* ZZZ */, lat_FG);
+ XDrawArc(dsply, contourWindow, contourGC /* ZZZ */,
+ lat_corner_X, lat_corner_Y,
+ lat_W, lat_H,
+ 0, 90*64);
+ XDrawLine(dsply, contourWindow, contourGC,
+ lat_quad_X, lat_quad_Y,
+ lat_quad_X, lat_quad_Y - lat_RADIUS);
+ XDrawLine(dsply, contourWindow, contourGC,
+ lat_quad_X, lat_quad_Y,
+ lat_quad_X + lat_RADIUS, lat_quad_Y);
+
+ /*---------------------------------------------------*
+ purty leettle tabs
+ *---------------------------------------------------*/
+ {
+ float a, xp, yp;
+ for (a=0; a<pi_half; a+=pi/16) {
+ xp = cos(a);
+ yp = -sin(a);
+ XDrawLine(dsply, contourWindow, contourGC,
+ (int)((lat_RADIUS-3) * xp + lat_quad_X),
+ (int)((lat_RADIUS-3) * yp + lat_quad_Y),
+ (int)((lat_RADIUS+3) * xp + lat_quad_X),
+ (int)((lat_RADIUS+3) * yp + lat_quad_Y));
+ }
+ }
+
+ /*---------------------------------------------------*
+ calculate and draw the latitudal pointer
+ *---------------------------------------------------*/
+ XSetFunction(dsply, contourGC, GXxor);
+ tip_x = (int)(sin(rot_phi) * (lat_RADIUS + dotExt)) + lat_quad_X;
+ tip_y = (int)(-cos(rot_phi) * (lat_RADIUS + dotExt)) + lat_quad_Y;
+ last_tip_lat_x = tip_x;
+ last_tip_lat_y = tip_y;
+ GSetForeground(contourGC,(float)stickColor,X);
+ GDrawLine(contourGC /* ZZZ */, contourWindow,
+ lat_quad_X, lat_quad_Y,
+ tip_x, tip_y, X);
+ XSetForeground(dsply, contourGC, dotColor);
+ XFillArc(dsply, contourWindow, contourGC /* ZZZ */,
+ tip_x - (dotSize>>1), tip_y - (dotSize>>1),
+ dotSize, dotSize,
+ 0, 360*64);
+ XSetFunction(dsply, contourGC, GXcopy);
+
+} /* draw_contour_latitude() */
+
+
+
+ /*---------------------------------------------------------------------*
+ draw_contour_slicing()
+ *---------------------------------------------------------------------*/
+void draw_contour_slicing()
+{
+
+ int tip_y, cut_spacing;
+#ifdef oldie
+ XDrawString(dsply, contourWindow, anotherGC,
+ slice_str_X, slice_str_Y,
+ "Slicer", 6);
+#else
+ char stringo[20];
+
+ sprintf(stringo,"Cuts: %d",max_cuts);
+ XClearArea(dsply, contourWindow,
+ slice_str_X,
+ slice_str_Y - 12,
+ contourSliceNum_W, 16, False);
+ XDrawString(dsply, contourWindow, anotherGC,
+ slice_str_X, slice_str_Y,
+ stringo, strlen(stringo));
+#endif
+
+ /*---------------------------------------------------*
+ put up the piece de resistance
+ *---------------------------------------------------*/
+ XClearArea(dsply, contourWindow,
+ contourSliceNum_X, contourSliceNum_Y,
+ contourSliceNum_W, contourSliceNum_H,
+ False);
+ XPutImage(dsply, contourWindow, contourGC,
+ slicer_image,
+ 0, 0,
+ slicer_image_X,
+ slicer_image_Y,
+ slicer_width, slicer_height);
+
+ /*---------------------------------------------------*
+ draw the number of slices
+ *---------------------------------------------------*/
+#define cuts_X (contourSliceNum_X + 15)
+#define cuts_Y (contourSliceNum_Y + 15)
+#define cuts_W 20
+#define cuts_H 85
+
+ XSetLineAttributes(dsply, trashGC, 1, LineSolid, CapButt, JoinMiter);
+ XClearArea(dsply, contourWindow,
+ cuts_X, cuts_Y, cuts_W, cuts_H, False);
+#ifdef oldie
+ cut_spacing = ( -(max_cuts - 1) + MAX_SLICES ) * cuts_H / MAX_SLICES;
+#else
+ {
+ float tmp;
+ tmp = (float)(-(max_cuts - 1) + MAX_SLICES) / MAX_SLICES;
+ cut_spacing = tmp*tmp * cuts_H;
+ if (cut_spacing < 1) cut_spacing = 1;
+ else if (cut_spacing > cuts_H) cut_spacing = cuts_H;
+ }
+#endif
+
+ XSetForeground(dsply, trashGC, moColor(violet0, pastel));
+ for (tip_y=cuts_Y+cuts_H; tip_y>=cuts_Y; tip_y-=cut_spacing) {
+ XDrawLine(dsply, contourWindow, trashGC,
+ cuts_X, tip_y,
+ cuts_X + cuts_W, tip_y);
+ }
+
+#define slide_Y (contourSliceNum_Y + 30)
+#define slide_H 55
+ {
+ float where;
+ int here;
+ where = (float)max_cuts/MAX_SLICES; /* [0..1] */
+ here = where * slide_H + slide_Y;
+ XSetForeground(dsply, contourGC, moColor(red1, normal));
+ XDrawLine(dsply, contourWindow, contourGC,
+ cuts_X + 45, here,
+ cuts_X + 55, here);
+ }
+
+} /* draw_contour_slicing() */
+
+
+ /*---------------------------------------------------------------------*
+ update_contour_longitude()
+
+ To be called for all subsequent updates after the contour window has
+ been mapped and drawn.
+ *---------------------------------------------------------------------*/
+void update_contour_longitude()
+{
+
+ int tip_x, tip_y;
+ char stringo[20];
+
+ /*---------------------------------------------------*
+ print out the longitude in degrees
+ *---------------------------------------------------*/
+ sprintf(stringo,"Longitude: %d",(int)(rot_theta * DEGREES));
+ XClearArea(dsply, contourWindow, long_str_X, long_str_Y - 12,
+ long_W + 50, 18, False);
+ XDrawString(dsply, contourWindow, anotherGC,
+ long_str_X, long_str_Y,
+ stringo, strlen(stringo));
+
+
+ /*---------------------------------------------------*
+ calculate and draw the longitudal pointer
+ *---------------------------------------------------*/
+ GSetForeground(contourGC,(float)stickColor,X);
+ GDrawLine(contourGC /* ZZZ */, contourWindow,
+ long_center_X, long_center_Y,
+ last_tip_long_x, last_tip_long_y, X);
+ GSetForeground(contourGC,(float)dotColor,X);
+ XFillArc(dsply, contourWindow, contourGC /* ZZZ */,
+ last_tip_long_x - (dotSize>>1), last_tip_long_y - (dotSize>>1),
+ dotSize, dotSize,
+ 0, 360*64);
+ tip_x = (int)(cos(rot_theta) * (long_RADIUS + dotExt)) + long_center_X;
+ tip_y = (int)(-sin(rot_theta) * (long_RADIUS + dotExt)) + long_center_Y;
+ last_tip_long_x = tip_x;
+ last_tip_long_y = tip_y;
+ GSetForeground(contourGC,(float)stickColor,X);
+ GDrawLine(contourGC /* ZZZ */, contourWindow,
+ long_center_X, long_center_Y,
+ tip_x, tip_y, X);
+ GSetForeground(contourGC,(float)dotColor,X);
+ XFillArc(dsply, contourWindow, contourGC /* ZZZ */,
+ tip_x - (dotSize>>1), tip_y - (dotSize>>1),
+ dotSize, dotSize,
+ 0, 360*64);
+
+} /* update_contour_longitude() */
+
+
+ /*---------------------------------------------------------------------*
+ update_contour_latitude()
+
+ To be called for all subsequent updates after the contour window has
+ been mapped and drawn.
+ *---------------------------------------------------------------------*/
+void update_contour_latitude()
+{
+
+ int tip_x, tip_y;
+ char stringo[20];
+
+ /*---------------------------------------------------*
+ print out the latitude in degrees
+ *---------------------------------------------------*/
+ sprintf(stringo,"Latitude: %d",(int)(rot_phi * DEGREES));
+ XClearArea(dsply, contourWindow, lat_str_X, lat_str_Y - 12,
+ lat_W, 18, False);
+ XDrawString(dsply, contourWindow, anotherGC,
+ lat_str_X, lat_str_Y,
+ stringo, strlen(stringo));
+
+ /*---------------------------------------------------*
+ calculate and draw the latitudal pointer
+ *---------------------------------------------------*/
+ GSetForeground(contourGC,(float)stickColor,X);
+ GDrawLine(contourGC /* ZZZ */, contourWindow,
+ lat_quad_X, lat_quad_Y,
+ last_tip_lat_x, last_tip_lat_y, X);
+ XSetForeground(dsply, contourGC, dotColor);
+ XFillArc(dsply, contourWindow, contourGC /* ZZZ */,
+ last_tip_lat_x - (dotSize>>1),
+ last_tip_lat_y - (dotSize>>1),
+ dotSize, dotSize,
+ 0, 360*64);
+ tip_x = (int)(sin(rot_phi) * (lat_RADIUS + dotExt)) + lat_quad_X;
+ tip_y = (int)(-cos(rot_phi) * (lat_RADIUS + dotExt)) + lat_quad_Y;
+ last_tip_lat_x = tip_x;
+ last_tip_lat_y = tip_y;
+ GSetForeground(contourGC,(float)stickColor,X);
+ GDrawLine(contourGC /* ZZZ */, contourWindow,
+ lat_quad_X, lat_quad_Y,
+ tip_x, tip_y, X);
+ XSetForeground(dsply, contourGC, dotColor);
+ XFillArc(dsply, contourWindow, contourGC /* ZZZ */,
+ tip_x - (dotSize>>1), tip_y - (dotSize>>1),
+ dotSize, dotSize,
+ 0, 360*64);
+
+} /* update_contour_latitude() */
diff --git a/src/graph/view3D/control3d.c.pamphlet b/src/graph/view3D/control3d.c.pamphlet
new file mode 100644
index 00000000..66148cf6
--- /dev/null
+++ b/src/graph/view3D/control3d.c.pamphlet
@@ -0,0 +1,1076 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D control3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _CONTROL3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "mouse11.bitmap"
+#include "mouse11.mask"
+
+#include "header.h"
+#include "cpanel.h"
+
+#include "util.H1"
+#include "XShade.H1"
+#include "XSpadFill.H1"
+#include "Gfun.H1"
+#include "all_3d.H1"
+
+/* Defines the pixmap for the arrow displayed in the scale window */
+#define zoomArrowN 11
+static XPoint zoomArrow[zoomArrowN] = {
+ {29,14},{38,23},{33,23},
+ {40,45},{53,45},
+ {29,69},
+ {5,45},{18,45},
+ {25,23},{20,23},{29,14} };
+
+/* Defines the pixmap for the arrows displayed in the translate window */
+#define translateArrowN 25
+static XPoint translateArrow[translateArrowN] = {
+ {55,2},{60,10},{58,10},{58,37},
+ {85,37},{85,35},{93,40},{85,45},{85,43},{58,43},
+ {58,70},{60,70},{55,78},{50,70},{52,70},{52,43},
+ {25,43},{25,45},{17,40},{25,35},{25,37},{52,37},
+ {52,10},{50,10},{55,2} };
+
+static int rotateX, rotateY, rotateR;
+
+/*
+ void drawColorMap ()
+ */
+
+void
+#ifdef _NO_PROTO
+drawColorMap ()
+#else
+drawColorMap (void)
+#endif
+{
+
+ controlPanelStruct *cp;
+ int i,shadeWidth;
+
+ /* Draw the color map window */
+
+ cp = viewport->controlPanel;
+
+ XClearArea(dsply,cp->controlWindow,5,colormapY,colormapW,colormapH,False);
+
+ /* if window is grayscale, show the grayscale colormap */
+ if (mono || (viewport->monoOn)) {
+ shadeWidth = 230/maxGreyShade;
+ for (i=0; i<maxGreyShade; i++) {
+ XChangeShade(dsply, i);
+ XShadeRectangle(dsply,cp->controlWindow,
+ colormapX + colorOffsetX + i*shadeWidth,
+ colormapY + colorOffsetY - 10, shadeWidth, 40);
+ }
+ } else {
+ GDrawString(globalGC2,cp->controlWindow,colorWidth,
+ colormapY + 13,"-",1,Xoption);
+ GDrawString(globalGC2,cp->controlWindow,30*colorWidth + 40,
+ colormapY + 13,"+",1,Xoption);
+ GDrawString(globalGC2,cp->controlWindow,colorWidth,
+ colormapY + 46,"-",1,Xoption);
+ GDrawString(globalGC2,cp->controlWindow,30*colorWidth + 40,
+ colormapY + 46,"+",1,Xoption);
+ for (i=0; i<totalHues; i++) {
+ GSetForeground(anotherGC, (float)XSolidColor(i,2), Xoption);
+ GDrawLine(anotherGC,cp->controlWindow,
+ colormapX + i*colorWidth + colorOffsetX,
+ colormapY + colorOffsetY,
+ colormapX + i*colorWidth + colorOffsetX,
+ colormapY + colorOffsetY + colorHeight,Xoption);
+ }
+
+ if (viewport->hueTop > totalHues-1) viewport->hueTop = totalHues-1;
+ if (viewport->hueOffset > totalHues-1) viewport->hueOffset = totalHues-1;
+
+ GSetForeground(globGC, (float)monoColor(7), Xoption);
+ /* Bottom (zmin) color indicator */
+ GDrawLine(globGC,cp->controlWindow,
+ colormapX + viewport->hueOffset * colorWidth + colorOffsetX,
+ colormapY + colorOffsetY+colorHeight,
+ colormapX + viewport->hueOffset * colorWidth + colorOffsetX,
+ colormapY + colorOffsetY+colorHeight+colorPointer,Xoption);
+
+ /* Top (zmax) color indicator */
+ GDrawLine(globGC,cp->controlWindow,
+ colormapX + viewport->hueTop * colorWidth+colorOffsetX,
+ colormapY + colorOffsetY,
+ colormapX + viewport->hueTop * colorWidth+colorOffsetX,
+ colormapY + colorOffsetY-colorPointer,Xoption);
+
+ /* Connect the bottom and top color indicator bars */
+ GSetForeground(globGC, (float)monoColor(0), Xoption);
+ GDrawLine(globGC,cp->controlWindow,
+ colormapX + viewport->hueOffset * colorWidth + colorOffsetX,
+ colormapY + colorOffsetY+colorHeight,
+ colormapX + viewport->hueTop * colorWidth+colorOffsetX,
+ colormapY + colorOffsetY,Xoption);
+ }
+ XSync(dsply,0);
+
+} /* drawColorMap() */
+
+
+/*******************************
+ * void writeControlTitle(w) *
+ * *
+ * We need the window argument *
+ * here because there are *
+ * multiple control panels in *
+ * 3D. *
+ *******************************/
+
+void
+#ifdef _NO_PROTO
+writeControlTitle (w)
+ Window w;
+#else
+writeControlTitle (Window w)
+#endif
+{
+ int strlength;
+
+ s = viewport->title;
+ strlength = strlen(s);
+ XClearArea(dsply,w,0,0,controlWidth,potA,False);
+
+ GSetForeground(anotherGC,(float)controlTitleColor,Xoption);
+ GDrawString(anotherGC,w,centerX(anotherGC,s,strlength,controlWidth),
+ 15,s,strlength,Xoption);
+
+} /* writeControlTitle() */
+
+
+/************************************/
+/*** void clearControlMessage() ***/
+/************************************/
+
+void
+#ifdef _NO_PROTO
+clearControlMessage ()
+#else
+clearControlMessage (void)
+#endif
+{
+ int strlength;
+
+ strcpy(viewport->controlPanel->message," ");
+ strlength = strlen(viewport->controlPanel->message);
+ GDrawImageString(globalGC1,viewport->controlPanel->controlWindow,
+ centerX(globalGC1,viewport->controlPanel->message,
+ strlength,controlWidth),
+ controlMessageY + globalFont->max_bounds.ascent + 8,
+ viewport->controlPanel->message,strlength,Xoption);
+
+}
+
+/************************************/
+/*** void writeControlMessage() ***/
+/************************************/
+
+void
+#ifdef _NO_PROTO
+writeControlMessage ()
+#else
+writeControlMessage (void)
+#endif
+{
+
+ int strlength;
+ controlPanelStruct *cp;
+
+ cp = viewport->controlPanel;
+ strlength = strlen(cp->message);
+ XClearArea(dsply,cp->controlWindow,
+ 0,controlMessageY+ globalFont->max_bounds.ascent + 8,
+ 0,controlMessageHeight,False);
+ GSetForeground(globalGC1, (float)controlMessageColor, Xoption);
+ GDrawImageString(globalGC1,cp->controlWindow,
+ centerX(globalGC1,cp->message,strlength,controlWidth),
+ controlMessageY + globalFont->max_bounds.ascent + 8,
+ cp->message,strlength,Xoption);
+
+ XFlush(dsply);
+
+}
+
+/*********************************/
+/*** void drawControlPanel() ***/
+/*********************************/
+
+void
+#ifdef _NO_PROTO
+drawControlPanel()
+#else
+drawControlPanel(void )
+#endif
+{
+
+ int offShade=14;
+ controlPanelStruct *cp;
+ int i, strlength;
+ char *s;
+
+ cp = viewport->controlPanel;
+
+ GSetForeground(trashGC, (float)foregroundColor, Xoption);
+
+ /* Draw border lines to separate the potentiometer, message, colormap and
+ button regions of the control panel. */
+ GSetLineAttributes(trashGC, 2, LineSolid, CapButt, JoinMiter, Xoption);
+
+ /* Draw a horizontal white line below the potentiometer area. */
+ GDrawLine(trashGC, cp->controlWindow, 0, potB-1, controlWidth, potB-1, Xoption);
+
+ /* Draw a horizontal white line above the rendering mode buttons. */
+ GDrawLine(trashGC, cp->controlWindow, 0, butA, controlWidth, butA, Xoption);
+
+ /* Draw a horizontal white line above the color mapping area. */
+ GDrawLine(trashGC, cp->controlWindow, 0, cmapA, controlWidth, cmapA, Xoption);
+
+ GSetLineAttributes(trashGC, 3, LineSolid, CapButt, JoinMiter, Xoption);
+ /* Draw a horizontal white line above the potentiometer area. */
+ GDrawLine(trashGC, cp->controlWindow, 0, potA, controlWidth, potA, Xoption);
+
+ /* Set the line width as 1 here because it is used below as well. */
+ GSetLineAttributes(trashGC, 1, LineSolid, CapButt, JoinMiter, Xoption);
+
+ /* Draw inner white lines around quit, hide panel, and reset buttons. */
+ GDrawLine(trashGC, cp->controlWindow, closeL, butA, closeL, butA+110, Xoption);
+
+ /* Write potentiometer titles on the control panel. */
+
+ writeControlTitle(cp->controlWindow);
+ GSetForeground(globGC, (float)controlPotHeaderColor, Xoption);
+
+ s = "Rotate";
+ GDrawString(globGC,cp->controlWindow,35,31+headerHeight,s,strlen(s),Xoption);
+ s = "Translate";
+ GDrawString(globGC,cp->controlWindow,202,31+headerHeight,s,strlen(s),Xoption);
+ s = "Scale";
+ GDrawString(globGC,cp->controlWindow,126,31+headerHeight,s,strlen(s),Xoption);
+
+ GSetForeground(globGC, (float)controlColorColor, Xoption);
+
+ /* Write labels on regular buttons, draw pixmaps on the potentiometers. */
+
+ GSetForeground(globalGC1, (float)monoColor(buttonColor), Xoption);
+
+ for (i=controlButtonsStart3D; i<(controlButtonsEnd3D); i++) {
+ /* special cases depending on initial conditions */
+
+ /* check if axes are set on or off */
+
+ if (((cp->buttonQueue[i]).buttonKey == axesOnOff) &&
+ (viewport->axesOn)) {
+ (cp->buttonQueue[i]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1, (float)backgroundColor, Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[axesOnOff]).buttonX,
+ (control->buttonQueue[axesOnOff]).buttonY,
+ (control->buttonQueue[axesOnOff]).buttonWidth,
+ (control->buttonQueue[axesOnOff]).buttonHeight);
+ GSetForeground(globalGC1, (float)foregroundColor, Xoption);
+ GDrawRectangle(globalGC1,control->controlWindow,
+ (control->buttonQueue[axesOnOff]).buttonX,
+ (control->buttonQueue[axesOnOff]).buttonY,
+ (control->buttonQueue[axesOnOff]).buttonWidth,
+ (control->buttonQueue[axesOnOff]).buttonHeight,Xoption);
+ }
+ } else {
+ if (((cp->buttonQueue[i]).buttonKey == axesOnOff) &&
+ (!viewport->axesOn)) {
+ (cp->buttonQueue[i]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,cp->controlWindow,
+ (cp->buttonQueue[i]).buttonX,
+ (cp->buttonQueue[i]).buttonY,
+ (cp->buttonQueue[i]).buttonWidth,
+ (cp->buttonQueue[i]).buttonHeight);
+ s = (control->buttonQueue[axesOnOff]).text;
+ strlength = strlen(s);
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[axesOnOff]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[axesOnOff]).buttonX +
+ centerX(processGC,s,strlength,
+ (control->buttonQueue[axesOnOff]).buttonWidth),
+ (control->buttonQueue[axesOnOff]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[axesOnOff]).buttonHeight),
+ s,strlength,Xoption);
+ } /* if mono */
+ }
+ } /* if axes */
+
+ /* check if bounding region is set on or off */
+
+ if (((cp->buttonQueue[i]).buttonKey == region3D) &&
+ (viewport->regionOn)) {
+ (cp->buttonQueue[i]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1, (float)backgroundColor, Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[region3D]).buttonX,
+ (control->buttonQueue[region3D]).buttonY,
+ (control->buttonQueue[region3D]).buttonWidth,
+ (control->buttonQueue[region3D]).buttonHeight);
+ GSetForeground(globalGC1, (float)foregroundColor, Xoption);
+ GDrawRectangle(globalGC1,control->controlWindow,
+ (control->buttonQueue[region3D]).buttonX,
+ (control->buttonQueue[region3D]).buttonY,
+ (control->buttonQueue[region3D]).buttonWidth,
+ (control->buttonQueue[region3D]).buttonHeight,Xoption);
+ }
+ } else {
+ if (((cp->buttonQueue[i]).buttonKey == region3D) &&
+ (!viewport->regionOn)) {
+ (cp->buttonQueue[i]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,cp->controlWindow,
+ (cp->buttonQueue[i]).buttonX,
+ (cp->buttonQueue[i]).buttonY,
+ (cp->buttonQueue[i]).buttonWidth,
+ (cp->buttonQueue[i]).buttonHeight);
+ s = (control->buttonQueue[region3D]).text;
+ strlength = strlen(s);
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[region3D]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[region3D]).buttonX +
+ centerX(processGC,s,strlength,
+ (control->buttonQueue[region3D]).buttonWidth),
+ (control->buttonQueue[region3D]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[region3D]).buttonHeight),
+ s,strlength,Xoption);
+ } /* if mono */
+ }
+ } /* if bounding region */
+
+ /* check if black and white is set on or off */
+
+ if (((cp->buttonQueue[i]).buttonKey == bwColor) && (mono)) {
+ (cp->buttonQueue[i]).text = " ";
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,cp->controlWindow,
+ (cp->buttonQueue[i]).buttonX,
+ (cp->buttonQueue[i]).buttonY,
+ (cp->buttonQueue[i]).buttonWidth,
+ (cp->buttonQueue[i]).buttonHeight);
+ } else {
+ if (((cp->buttonQueue[i]).buttonKey == bwColor) && viewport->monoOn) {
+ (cp->buttonQueue[i]).textColor = onColor;
+ s = (control->buttonQueue[bwColor]).text;
+ strlength = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[bwColor]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[bwColor]).buttonX +
+ centerX(processGC,s,strlength,
+ (control->buttonQueue[bwColor]).buttonWidth),
+ (control->buttonQueue[bwColor]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[bwColor]).buttonHeight),
+ s,strlength,Xoption);
+ } else {
+ if (((cp->buttonQueue[i]).buttonKey == bwColor) && (!viewport->monoOn)) {
+ (cp->buttonQueue[i]).textColor = offColor;
+ s = (control->buttonQueue[bwColor]).text;
+ strlength = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[bwColor]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[bwColor]).buttonX +
+ centerX(processGC,s,strlength,
+ (control->buttonQueue[bwColor]).buttonWidth),
+ (control->buttonQueue[bwColor]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[bwColor]).buttonHeight),
+ s,strlength,Xoption);
+ }
+ }
+ } /* if black and white */
+
+ /* check if object rotation is set on or off */
+
+ if (((cp->buttonQueue[i]).buttonKey == objectr) &&
+ (viewport->objectrOn)) {
+ (control->buttonQueue[objectr]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1, (float)backgroundColor, Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[objectr]).buttonX,
+ (control->buttonQueue[objectr]).buttonY,
+ (control->buttonQueue[objectr]).buttonWidth,
+ (control->buttonQueue[objectr]).buttonHeight);
+ GSetForeground(globalGC1, (float)foregroundColor, Xoption);
+ GDrawRectangle(globalGC1,control->controlWindow,
+ (control->buttonQueue[objectr]).buttonX,
+ (control->buttonQueue[objectr]).buttonY,
+ (control->buttonQueue[objectr]).buttonWidth,
+ (control->buttonQueue[objectr]).buttonHeight,Xoption);
+ }
+ } else {
+ if (((cp->buttonQueue[i]).buttonKey == objectr) &&
+ (!viewport->objectrOn)) {
+ (control->buttonQueue[objectr]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[objectr]).buttonX,
+ (control->buttonQueue[objectr]).buttonY,
+ (control->buttonQueue[objectr]).buttonWidth,
+ (control->buttonQueue[objectr]).buttonHeight);
+ GSetForeground(globalGC1, (float)foregroundColor, Xoption);
+ GDrawRectangle(globalGC1,control->controlWindow,
+ (control->buttonQueue[objectr]).buttonX,
+ (control->buttonQueue[objectr]).buttonY,
+ (control->buttonQueue[objectr]).buttonWidth,
+ (control->buttonQueue[objectr]).buttonHeight,Xoption);
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[objectr]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[objectr]).buttonX +
+ centerX(processGC,(control->buttonQueue[objectr]).text,
+ strlen((control->buttonQueue[objectr]).text),
+ (control->buttonQueue[objectr]).buttonWidth),
+ (control->buttonQueue[objectr]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[objectr]).buttonHeight),
+ (control->buttonQueue[objectr]).text,
+ strlen((control->buttonQueue[objectr]).text),Xoption);
+ }
+ } /* else not object rotation */
+ } /* if object rotation */
+
+ /* check if origin rotation is set on or off */
+
+ if (((cp->buttonQueue[i]).buttonKey == originr) &&
+ (viewport->originrOn)) {
+ (control->buttonQueue[originr]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1, (float)backgroundColor, Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[originr]).buttonX,
+ (control->buttonQueue[originr]).buttonY,
+ (control->buttonQueue[originr]).buttonWidth,
+ (control->buttonQueue[originr]).buttonHeight);
+ GSetForeground(globalGC1, (float)foregroundColor, Xoption);
+ GDrawRectangle(globalGC1,control->controlWindow,
+ (control->buttonQueue[originr]).buttonX,
+ (control->buttonQueue[originr]).buttonY,
+ (control->buttonQueue[originr]).buttonWidth,
+ (control->buttonQueue[originr]).buttonHeight,Xoption);
+ }
+ } else {
+ if (((cp->buttonQueue[i]).buttonKey == originr) &&
+ (!viewport->originrOn)) {
+ (control->buttonQueue[originr]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[originr]).buttonX,
+ (control->buttonQueue[originr]).buttonY,
+ (control->buttonQueue[originr]).buttonWidth,
+ (control->buttonQueue[originr]).buttonHeight);
+ GSetForeground(globalGC1, (float)foregroundColor, Xoption);
+ GDrawRectangle(globalGC1,control->controlWindow,
+ (control->buttonQueue[originr]).buttonX,
+ (control->buttonQueue[originr]).buttonY,
+ (control->buttonQueue[originr]).buttonWidth,
+ (control->buttonQueue[originr]).buttonHeight,Xoption);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[originr]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[originr]).buttonX +
+ centerX(processGC,(control->buttonQueue[originr]).text,
+ strlen((control->buttonQueue[originr]).text),
+ (control->buttonQueue[originr]).buttonWidth),
+ (control->buttonQueue[originr]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[originr]).buttonHeight),
+ (control->buttonQueue[originr]).text,
+ strlen((control->buttonQueue[originr]).text),Xoption);
+ }
+ } /* else not origin rotation */
+ } /* if origin rotation */
+
+ /* check if zoom X is set on or off */
+
+ if (((cp->buttonQueue[i]).buttonKey == zoomx) &&
+ (viewport->zoomXOn)) {
+ (control->buttonQueue[zoomx]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1, (float)backgroundColor, Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[zoomx]).buttonX,
+ (control->buttonQueue[zoomx]).buttonY,
+ (control->buttonQueue[zoomx]).buttonWidth,
+ (control->buttonQueue[zoomx]).buttonHeight);
+ GSetForeground(globalGC1, (float)foregroundColor, Xoption);
+ GDrawRectangle(globalGC1,control->controlWindow,
+ (control->buttonQueue[zoomx]).buttonX,
+ (control->buttonQueue[zoomx]).buttonY,
+ (control->buttonQueue[zoomx]).buttonWidth,
+ (control->buttonQueue[zoomx]).buttonHeight,Xoption);
+ }
+ } else {
+ if (((cp->buttonQueue[i]).buttonKey == zoomx) &&
+ (!viewport->zoomXOn)) {
+ (control->buttonQueue[zoomx]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[zoomx]).buttonX,
+ (control->buttonQueue[zoomx]).buttonY,
+ (control->buttonQueue[zoomx]).buttonWidth,
+ (control->buttonQueue[zoomx]).buttonHeight);
+ GSetForeground(globalGC1, (float)foregroundColor, Xoption);
+ GDrawRectangle(globalGC1,control->controlWindow,
+ (control->buttonQueue[zoomx]).buttonX,
+ (control->buttonQueue[zoomx]).buttonY,
+ (control->buttonQueue[zoomx]).buttonWidth,
+ (control->buttonQueue[zoomx]).buttonHeight,Xoption);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[zoomx]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[zoomx]).buttonX +
+ centerX(processGC,(control->buttonQueue[zoomx]).text,
+ strlen((control->buttonQueue[zoomx]).text),
+ (control->buttonQueue[zoomx]).buttonWidth),
+ (control->buttonQueue[zoomx]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[zoomx]).buttonHeight),
+ (control->buttonQueue[zoomx]).text,
+ strlen((control->buttonQueue[zoomx]).text),Xoption);
+ }
+ } /* else not zoom X */
+ } /* if zoom X */
+
+ /* check if zoom Y is set on or off */
+
+ if (((cp->buttonQueue[i]).buttonKey == zoomy) &&
+ (viewport->zoomYOn)) {
+ (control->buttonQueue[zoomy]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1, (float)backgroundColor, Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[zoomy]).buttonX,
+ (control->buttonQueue[zoomy]).buttonY,
+ (control->buttonQueue[zoomy]).buttonWidth,
+ (control->buttonQueue[zoomy]).buttonHeight);
+ GSetForeground(globalGC1, (float)foregroundColor, Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[zoomy]).buttonX,
+ (control->buttonQueue[zoomy]).buttonY,
+ (control->buttonQueue[zoomy]).buttonWidth,
+ (control->buttonQueue[zoomy]).buttonHeight,Xoption);
+ }
+ } else {
+ if (((cp->buttonQueue[i]).buttonKey == zoomy) &&
+ (!viewport->zoomYOn)) {
+ (control->buttonQueue[zoomy]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[zoomy]).buttonX,
+ (control->buttonQueue[zoomy]).buttonY,
+ (control->buttonQueue[zoomy]).buttonWidth,
+ (control->buttonQueue[zoomy]).buttonHeight);
+ GSetForeground(globalGC1, (float)foregroundColor, Xoption);
+ GDrawRectangle(globalGC1,control->controlWindow,
+ (control->buttonQueue[zoomy]).buttonX,
+ (control->buttonQueue[zoomy]).buttonY,
+ (control->buttonQueue[zoomy]).buttonWidth,
+ (control->buttonQueue[zoomy]).buttonHeight,Xoption);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[zoomy]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[zoomy]).buttonX +
+ centerX(processGC,(control->buttonQueue[zoomy]).text,
+ strlen((control->buttonQueue[zoomy]).text),
+ (control->buttonQueue[zoomy]).buttonWidth),
+ (control->buttonQueue[zoomy]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[zoomy]).buttonHeight),
+ (control->buttonQueue[zoomy]).text,
+ strlen((control->buttonQueue[zoomy]).text),Xoption);
+ }
+ } /* else not zoom Y */
+ } /* if zoom Y */
+
+ /* check if zoom Z is set on or off */
+
+ if (((cp->buttonQueue[i]).buttonKey == zoomz) &&
+ (viewport->zoomZOn)) {
+ (control->buttonQueue[zoomz]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1, (float)backgroundColor, Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[zoomz]).buttonX,
+ (control->buttonQueue[zoomz]).buttonY,
+ (control->buttonQueue[zoomz]).buttonWidth,
+ (control->buttonQueue[zoomz]).buttonHeight);
+ GSetForeground(globalGC1, (float)foregroundColor, Xoption);
+ GDrawRectangle(globalGC1,control->controlWindow,
+ (control->buttonQueue[zoomz]).buttonX,
+ (control->buttonQueue[zoomz]).buttonY,
+ (control->buttonQueue[zoomz]).buttonWidth,
+ (control->buttonQueue[zoomz]).buttonHeight,Xoption);
+ }
+ } else {
+ if (((cp->buttonQueue[i]).buttonKey == zoomz) &&
+ (!viewport->zoomZOn)) {
+ (control->buttonQueue[zoomz]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[zoomz]).buttonX,
+ (control->buttonQueue[zoomz]).buttonY,
+ (control->buttonQueue[zoomz]).buttonWidth,
+ (control->buttonQueue[zoomz]).buttonHeight);
+ GSetForeground(globalGC1, (float)foregroundColor, Xoption);
+ GDrawRectangle(globalGC1,control->controlWindow,
+ (control->buttonQueue[zoomz]).buttonX,
+ (control->buttonQueue[zoomz]).buttonY,
+ (control->buttonQueue[zoomz]).buttonWidth,
+ (control->buttonQueue[zoomz]).buttonHeight,Xoption);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[zoomz]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[zoomz]).buttonX +
+ centerX(processGC,(control->buttonQueue[zoomz]).text,
+ strlen((control->buttonQueue[zoomz]).text),
+ (control->buttonQueue[zoomz]).buttonWidth),
+ (control->buttonQueue[zoomz]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[zoomz]).buttonHeight),
+ (control->buttonQueue[zoomz]).text,
+ strlen((control->buttonQueue[zoomz]).text),Xoption);
+ }
+ } /* else not zoom Y */
+ } /* if zoom Y */
+
+ /* check if outline is set on or off */
+
+ if (((cp->buttonQueue[i]).buttonKey == outlineOnOff) &&
+ (viewData.outlineRenderOn)) {
+ (cp->buttonQueue[i]).textColor = onColor;
+ } else {
+ if (((cp->buttonQueue[i]).buttonKey == outlineOnOff) &&
+ !(viewData.outlineRenderOn)) {
+ (cp->buttonQueue[i]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,cp->controlWindow,
+ (cp->buttonQueue[i]).buttonX,
+ (cp->buttonQueue[i]).buttonY,
+ (cp->buttonQueue[i]).buttonWidth,
+ (cp->buttonQueue[i]).buttonHeight);
+ s = (control->buttonQueue[outlineOnOff]).text;
+ strlength = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[outlineOnOff]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[outlineOnOff]).buttonX +
+ centerX(processGC,s,strlength,
+ (control->buttonQueue[outlineOnOff]).buttonWidth),
+ (control->buttonQueue[outlineOnOff]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[outlineOnOff]).buttonHeight),
+ s,strlength,Xoption);
+ } /* if mono */
+ } /* outline off */
+ } /* outline on */
+
+ /* Draw the button window border */
+
+ GDraw3DButtonOut(globalGC1,cp->controlWindow,
+ (cp->buttonQueue[i]).buttonX, (cp->buttonQueue[i]).buttonY,
+ (cp->buttonQueue[i]).buttonWidth,
+ (cp->buttonQueue[i]).buttonHeight,Xoption);
+
+ GSetForeground(trashGC,
+ (float)monoColor((cp->buttonQueue[i]).textColor), Xoption);
+ switch (i) {
+ case rotate:
+ GDrawArc(trashGC, cp->controlWindow,
+ rotateX, rotateY, rotateR, rotateR, 0, 360*64, Xoption);
+ break;
+
+ case zoom:
+ GDrawLines(trashGC, cp->controlWindow, zoomArrow, zoomArrowN,
+ CoordModeOrigin, Xoption);
+ break;
+
+ case translate:
+ GDrawLines(trashGC, cp->controlWindow, translateArrow,
+ translateArrowN, CoordModeOrigin, Xoption);
+ break;
+
+ default:
+ s = (cp->buttonQueue[i]).text;
+ strlength = strlen(s);
+ GDrawString(trashGC, cp->controlWindow,
+ (cp->buttonQueue[i]).buttonX +
+ centerX(processGC,s,strlength,
+ (cp->buttonQueue[i]).buttonWidth),
+ (cp->buttonQueue[i]).buttonY +
+ centerY(processGC,
+ (cp->buttonQueue[i]).buttonHeight),s,strlen(s),Xoption);
+ break;
+ };
+
+ if ((cp->buttonQueue[i]).pot) {
+ /* draw horizontal and vertical centerlines */
+
+ GDrawLine(globalGC1,cp->controlWindow,
+ (cp->buttonQueue[i]).buttonX + (cp->buttonQueue[i]).xHalf,
+ (cp->buttonQueue[i]).buttonY,
+ (cp->buttonQueue[i]).buttonX + (cp->buttonQueue[i]).xHalf,
+ (cp->buttonQueue[i]).buttonY + 2*(cp->buttonQueue[i]).yHalf,Xoption);
+
+ GDrawLine(globalGC1,cp->controlWindow,
+ (cp->buttonQueue[i]).buttonX,
+ (cp->buttonQueue[i]).buttonY + (cp->buttonQueue[i]).yHalf,
+ (cp->buttonQueue[i]).buttonX + 2*(cp->buttonQueue[i]).xHalf,
+ (cp->buttonQueue[i]).buttonY + (cp->buttonQueue[i]).yHalf,Xoption);
+ }
+ }
+
+ /* refresh the latest message */
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+
+ /* Draw the color map window */
+ cp = viewport->controlPanel;
+ drawColorMap();
+ XFlush(dsply);
+
+} /* drawControlPanel() */
+
+
+/*****************************
+ * void getControlXY() *
+ * *
+ * Determines the x and y *
+ * coordinate where the *
+ * control panel is to be *
+ * placed, based upon where *
+ * the mouse button was *
+ * pressed within the graph *
+ * viewport window. *
+ *****************************/
+
+controlXY
+#ifdef _NO_PROTO
+getControlXY (whereDoYouWantPanel)
+ int whereDoYouWantPanel;
+#else
+getControlXY (int whereDoYouWantPanel)
+#endif
+{
+
+ XWindowAttributes wAttrib;
+ controlXY cXY;
+ int viewX, viewY, viewW, viewH, tmp=1;
+ Window rootW, parentW, *childrenWs, tmpW;
+ unsigned int nChildren;
+
+ tmpW = viewport->titleWindow;
+ while(tmp) {
+ XQueryTree(dsply,tmpW,&rootW,&parentW,&childrenWs,&nChildren);
+ XFree(childrenWs);
+ if (parentW == rtWindow) {
+ tmp = 0;
+ } else {
+ tmpW = parentW;
+ }
+ }
+ XGetWindowAttributes(dsply,tmpW,&wAttrib);
+
+ viewX = wAttrib.x;
+ viewY = wAttrib.y;
+ viewW = wAttrib.width;
+ viewH = wAttrib.height;
+
+ if (whereDoYouWantPanel) {
+ switch (whereDoYouWantPanel) {
+ case 1: /* right */
+ cXY.putX = viewX + viewW;
+ cXY.putY = viewY;
+ break;
+ case 2: /* bottom */
+ cXY.putX = viewX + (viewW - controlWidth)/2; /* center it */
+ cXY.putY = viewY + viewH;
+ break;
+ case 3: /* left */
+ cXY.putX = viewX - controlWidth - borderWidth;
+ cXY.putY = viewY;
+ break;
+ case 4: /* top */
+ cXY.putX = viewX + (viewW - controlWidth)/2; /* center it */
+ cXY.putY = viewY - controlHeight - borderHeight;
+ }
+ } else {
+ if ((physicalWidth - (viewX + viewW)) >= controlWidth) {
+ cXY.putX = viewX + viewW;
+ cXY.putY = viewY;
+ } else if ((physicalHeight - (viewY + viewH)) >= controlHeight) {
+ cXY.putX = viewX + (viewW - controlWidth)/2; /* center it */
+ cXY.putY = viewY + viewH;
+ } else if (viewX >= controlWidth) {
+ cXY.putX = viewX - controlWidth - borderWidth;
+ cXY.putY = viewY;
+ } else if (viewY >= controlHeight) {
+ cXY.putX = viewX + (viewW - controlWidth)/2; /* center it */
+ cXY.putY = viewY - controlHeight - borderHeight;
+ } else { /* put inside of viewport */
+ cXY.putX = viewX + viewW - controlWidth;
+ cXY.putY = viewY + viewH - controlHeight;
+ }
+ }
+ if (cXY.putX < 0) cXY.putX = 0;
+ if (cXY.putY < 0) cXY.putY = 0;
+ return(cXY);
+
+}
+
+
+
+/************************************************/
+/*** controlPanelStruct *makeControlPanel() ***/
+/************************************************/
+
+controlPanelStruct *
+#ifdef _NO_PROTO
+makeControlPanel ()
+#else
+makeControlPanel (void)
+#endif
+{
+
+ Window cw;
+ int i, num;
+ controlPanelStruct *control;
+ buttonStruct *buttons;
+ controlXY cXY;
+ XSetWindowAttributes cwAttrib, controlAttrib;
+ XSizeHints sizehint;
+ Pixmap mousebits, mousemask;
+ XColor foreColor, backColor;
+
+ if (!(control = (controlPanelStruct *)saymem("control.c",1,
+ sizeof(controlPanelStruct)))) {
+ fprintf(stderr,"Ran out of memory trying to create control panel.\n");
+ exitWithAck(RootWindow(dsply,scrn),Window,-1);
+ }
+
+ cXY = getControlXY(0);
+
+ mousebits = XCreateBitmapFromData(dsply,rtWindow, mouseBitmap_bits,
+ mouseBitmap_width, mouseBitmap_height);
+ mousemask = XCreateBitmapFromData(dsply,rtWindow, mouseMask_bits,
+ mouseMask_width, mouseMask_height);
+ cwAttrib.background_pixel = backgroundColor;
+ cwAttrib.border_pixel = foregroundColor;
+ cwAttrib.event_mask = controlMASK;
+ cwAttrib.colormap = colorMap;
+ cwAttrib.override_redirect = overrideManager;
+ foreColor.pixel = controlCursorForeground;
+ XQueryColor(dsply,colorMap,&foreColor);
+ backColor.pixel = controlCursorBackground;
+ XQueryColor(dsply,colorMap,&backColor);
+ cwAttrib.cursor = XCreatePixmapCursor(dsply,mousebits,
+ mousemask, &foreColor,&backColor,
+ mouseBitmap_x_hot,mouseBitmap_y_hot);
+ cw = XCreateWindow(dsply,rtWindow,
+ cXY.putX,cXY.putY,controlWidth,controlHeight,3,
+ CopyFromParent,InputOutput,CopyFromParent,
+ controlCreateMASK,&cwAttrib);
+
+ sizehint.flags = PPosition | PSize;
+ sizehint.x = cXY.putX;
+ sizehint.y = cXY.putY;
+ sizehint.width = controlWidth;
+ sizehint.height = controlHeight;
+ /*** the None stands for icon pixmap ***/
+ XSetNormalHints(dsply,cw,&sizehint);
+ XSetStandardProperties(dsply,cw,"3D Control Panel","3D Control Panel",
+ None,NULL,0,&sizehint);
+
+ /* Define and assign a mouse cursor */
+ control->controlWindow = cw;
+
+ num = initButtons(control->buttonQueue);
+ buttons = control->buttonQueue;
+ for (i=controlButtonsStart3D; i<(controlButtonsEnd3D); i++) {
+ controlAttrib.event_mask = (control->buttonQueue[i]).mask;
+ (control->buttonQueue[i]).self = XCreateWindow(dsply,cw,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,
+ 0,0,InputOnly,CopyFromParent,
+ buttonCreateMASK,&controlAttrib);
+ XMakeAssoc(dsply,table,(control->buttonQueue[i]).self,
+ &((control->buttonQueue[i]).buttonKey));
+ /* use buttonKey and not i because buttonKey has a permanent address */
+
+ XMapWindow(dsply,(control->buttonQueue[i]).self);
+
+ } /* for each button */
+
+
+ /* Set up the potentiometer pixmaps. */
+ for (i=0; i<zoomArrowN; i++) {
+ zoomArrow[i].x += buttons[zoom].buttonX;
+ zoomArrow[i].y += buttons[zoom].buttonY;
+ }
+ for (i=0; i<translateArrowN; i++) {
+ translateArrow[i].x += buttons[translate].buttonX;
+ translateArrow[i].y += buttons[translate].buttonY;
+ }
+
+ rotateX = control->buttonQueue[rotate].buttonX+17;
+ rotateY = control->buttonQueue[rotate].buttonY+2;
+ rotateR = control->buttonQueue[rotate].buttonHeight-4;
+
+ strcpy(control->message," ");
+
+ /* Create the color mapping window */
+ controlAttrib.event_mask = colorMASK;
+ control->colormapWindow = XCreateWindow(dsply,cw, colorWidth,colormapY,
+ colormapW,colormapH,0, 0,InputOnly,
+ CopyFromParent, colormapCreateMASK,
+ &controlAttrib);
+ XMapWindow(dsply,control->colormapWindow);
+ viewport->justMadeControl = yes;
+
+ return(control);
+
+} /* makeControlPanel() */
+
+
+
+
+/******************************************
+ * void putControlPanelSomewhere() *
+ * This routine puts up the control panel *
+ * associated with the viewport passed *
+ * in. It first tries to put it to the *
+ * right of the viewport. If there isn't *
+ * enough room, it tries the bottom and *
+ * so on going clockwise. If the viewport *
+ * is too big and there is no room to put *
+ * the control panel outside of it, the *
+ * control panel is placed on the bottom *
+ * right hand corner of the viewport. *
+ *****************************************/
+
+void
+#ifdef _NO_PROTO
+putControlPanelSomewhere (whereDoesPanelGo)
+ int whereDoesPanelGo;
+#else
+putControlPanelSomewhere (int whereDoesPanelGo)
+#endif
+{
+ controlPanelStruct *control;
+ controlXY whereControl;
+
+ control = viewport->controlPanel;
+ whereControl = getControlXY(whereDoesPanelGo);
+
+ viewport->haveControl = yes;
+
+ XRaiseWindow(dsply,control->controlWindow);
+ XMoveWindow(dsply, control->controlWindow,
+ whereControl.putX, whereControl.putY);
+
+ drawControlPanel();
+ XSync(dsply,0);
+ if (viewport->justMadeControl) {
+ XMapWindow(dsply,control->controlWindow);
+ viewport->justMadeControl = no;
+ }
+ XMapWindow(dsply,control->controlWindow);
+ XFlush(dsply);
+
+}
+
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/cpanel.h b/src/graph/view3D/cpanel.h
new file mode 100755
index 00000000..37da0202
--- /dev/null
+++ b/src/graph/view3D/cpanel.h
@@ -0,0 +1,103 @@
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+
+
+/*
+to be included in control.c for drawing the colormap and
+process.c for getting the mouse input
+ */
+
+#define controlMASK (ButtonPressMask + ButtonReleaseMask + ExposureMask)
+#define potMASK (ButtonPressMask + ButtonReleaseMask + ButtonMotionMask + LeaveWindowMask)
+#define buttonMASK (ButtonPressMask + ButtonReleaseMask + ButtonMotionMask + LeaveWindowMask)
+#define colorMASK (ButtonPressMask + ButtonReleaseMask + ButtonMotionMask + LeaveWindowMask)
+
+
+#define mouseWait 50
+ /* make mouse grab for stationary mouse on a potentiometer slower */
+
+#define controlCreateMASK CWBackPixel | CWBorderPixel | CWEventMask |CWCursor |CWColormap | CWOverrideRedirect
+#define buttonCreateMASK CWEventMask
+#define messageCreateMASK 0
+#define colormapCreateMASK CWEventMask
+
+#define controlWidth 300
+#define controlHeight 400
+#define quitWidth 63
+#define quitHeight 107
+#define saveWidth 63
+#define saveHeight 107
+#define borderWidth 22
+#define borderHeight 45
+
+
+#define controlCursorForeground monoColor(4)
+#define controlCursorBackground monoColor(54)
+#define controlTitleColor monoColor(36)
+#define controlPotHeaderColor monoColor(52)
+#define controlColorColor monoColor(13)
+#define controlColorSignColor monoColor(22)
+
+#define headerHeight headerFont->max_bounds.ascent
+#define controlMessageHeight globalFont->max_bounds.ascent +globalFont->max_bounds.descent+4
+
+#define potA 25 /* y coordinate of line dividing
+ potentiometers from stuff above it */
+#define potB 173 /* y coordinate of line dividing
+ potentiometers from title */
+
+#define cmapA 233 /* y coordinate of line dividing
+ colormap from stuff above it */
+
+#define butA ((cp->buttonQueue[render]).buttonY - 5)
+
+#define closeL ((cp->buttonQueue[closeAll]).buttonX - 5)
+#define closeA ((cp->buttonQueue[closeAll]).buttonY - 5)
+
+#define controlMessageY 181
+#define controlMessageColor monoColor(68)
+
+#define offColor 13
+#define onColor 98
+#define modeColor 44
+
+#define colormapX 21
+#define colormapY 240
+#define colormapW 290
+#define colormapH 48
+#define colorWidth 8
+#define colorHeight 8
+#define colorOffset 3
+#define colorOffsetX 24
+#define colorOffsetY 16
+#define colorPointer 16
diff --git a/src/graph/view3D/draw.h b/src/graph/view3D/draw.h
new file mode 100755
index 00000000..1239f2a9
--- /dev/null
+++ b/src/graph/view3D/draw.h
@@ -0,0 +1,73 @@
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+
+#define meshOutline monoColor(140)
+#define opaqueOutline monoColor(85)
+#define opaqueForeground backgroundColor
+
+
+#define clipOffset 500
+
+/* recalculation occurs if any of these situations have occured */
+
+#define recalc (rotated || zoomed || translated || !finishedList || \
+ firstTime || switchedPerspective || changedEyeDistance)
+
+
+/*** projection macros if matrices are not used ***/
+#define projPersp(z) (viewData.eyeDistance / (z+viewData.eyeDistance))
+
+#define proj2PX(x,y) -(x*cosTheta + y*sinTheta)
+#define proj2PY(x,y,z) -(y*cosTheta*cosPhi - x*sinTheta*cosPhi + z*sinPhi)
+
+/*** For clipping points ***/
+
+#define behindClipPlane(pz) lessThan(pz,viewData.clipPlane)
+
+#define outsideClippedBoundary(x,y,z) (lessThan(x,viewData.clipXmin) || \
+ greaterThan(x,viewData.clipXmax) || \
+ lessThan(y,viewData.clipYmin) || \
+ greaterThan(y,viewData.clipYmax) || \
+ lessThan(z,viewData.clipZmin) || \
+ greaterThan(z,viewData.clipZmax) || \
+ isNaNPoint(x,y,z))
+#include <limits.h>
+
+#define NotPoint (SHRT_MAX)
+#define eqNANQ(x) (x == NotPoint)
+
+
+
+/* Tests for NaN clipping should be added in here. */
+
+
diff --git a/src/graph/view3D/eventnames.h b/src/graph/view3D/eventnames.h
new file mode 100755
index 00000000..ecfcab31
--- /dev/null
+++ b/src/graph/view3D/eventnames.h
@@ -0,0 +1,70 @@
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+
+static char *event_name[] = {
+ "", /* 0 */
+ "", /* 1 */
+ "KeyPress", /* 2 */
+ "KeyRelease", /* 3 */
+ "ButtonPress", /* 4 */
+ "ButtonRelease", /* 5 */
+ "MotionNotify", /* 6 */
+ "EnterNotify", /* 7 */
+ "LeaveNotify", /* 8 */
+ "FocusIn", /* 9 */
+ "FocusOut", /* 10 */
+ "KeymapNotify", /* 11 */
+ "Expose", /* 12 */
+ "GraphicsExpose", /* 13 */
+ "NoExpose", /* 14 */
+ "VisibilityNotify", /* 15 */
+ "CreateNotify", /* 16 */
+ "DestroyNotify", /* 17 */
+ "UnmapNotify", /* 18 */
+ "MapNotify", /* 19 */
+ "MapRequest", /* 20 */
+ "ReparentNotify", /* 21 */
+ "ConfigureNotify", /* 22 */
+ "ConfigureRequest", /* 23 */
+ "GravityNotify", /* 24 */
+ "ResizeRequest", /* 25 */
+ "CirculateNotify", /* 26 */
+ "CirculateRequest", /* 27 */
+ "PropertyNotify", /* 28 */
+ "SelectionClear", /* 29 */
+ "SelectionRequest", /* 30 */
+ "SelectionNotify", /* 31 */
+ "ColormapNotify", /* 32 */
+ "ClientMessage", /* 33 */
+ "MappingNotify" /* 34 */
+ };
diff --git a/src/graph/view3D/globals.h b/src/graph/view3D/globals.h
new file mode 100755
index 00000000..a779690f
--- /dev/null
+++ b/src/graph/view3D/globals.h
@@ -0,0 +1,163 @@
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+
+extern int scrn;
+extern Display *dsply;
+extern XFontStruct *globalFont, *buttonFont, *headerFont,
+ *titleFont, *graphFont,
+ *lightingFont, *volumeFont, *quitFont, *saveFont,
+ *serverFont;
+extern XrmDatabase rDB;
+
+extern char scaleReport[5], deltaXReport[5], deltaYReport[5];
+extern unsigned long *spadColors;
+extern int followMouse, gotToggle, viewportKeyNum;
+extern Window rtWindow, quitWindow, saveWindow;
+extern GC globalGC1, globalGC2, anotherGC, globGC, trashGC,
+ componentGC, opaqueGC, renderGC,
+ controlMessageGC, lightingGC, volumeGC, quitGC,
+ saveGC, graphGC;
+extern XSizeHints viewSizeHints;
+extern HashTable *table;
+extern Colormap colorMap;
+extern int Socket, ack;
+
+extern GC processGC;
+extern viewPoints *viewport;
+extern controlPanelStruct *control;
+extern XGCValues gcVals;
+extern char *s;
+extern int someInt;
+
+extern unsigned long foregroundColor, backgroundColor;
+extern int mono, totalColors,
+ totalHues, totalSolidShades, totalSolid,
+ totalDitheredAndSolids,totalShades;
+
+extern int drawMore;
+extern int spadMode,spadDraw;
+extern int spadSignalReceived;
+extern int inNextEvent;
+extern jmp_buf jumpFlag;
+
+extern char errorStr[80];
+
+extern view3DStruct viewData;
+
+extern Window lightingWindow, lightingAxes;
+extern float lightPointer[3], tempLightPointer[3];
+extern float lightIntensity, tempLightIntensity;
+extern float backLightIntensity;
+
+extern char filename[256];
+
+
+ /** stuff from draw viewport routines */
+extern float sinTheta, sinPhi, cosTheta, cosPhi,
+ viewScale, viewScaleX, viewScaleY, viewScaleZ, reScale;
+extern int xCenter, yCenter;
+extern XWindowAttributes vwInfo;
+extern XWindowAttributes graphWindowAttrib;
+extern XPoint *quadMesh;
+extern int *xPts;
+extern XImage *imageX;
+
+extern float eyePoint[3];
+
+extern XPoint polygonMesh[20];
+
+extern int saveFlag;
+extern int firstTime, noTrans, startup;
+extern int redrawView;
+extern int finishedList, redoSmooth, redoColor, zoomed,
+ rotated, switchedPerspective, changedEyeDistance,
+ translated, changedIntensity, movingLight, writeImage,
+ pixelSetFlag, redoDither, multiColorFlag;
+extern poly *quickList;
+
+extern int viewAloned;
+
+extern viewTriple corners[8], clipCorners[8];
+extern boxSideStruct box[6], clipBox[6];
+extern int axesXY[3][4];
+extern float axesZ[3][2];
+
+extern viewTriple *splitPoints;
+extern int resMax;
+
+extern Window volumeWindow;
+extern int frustrumVertex;
+extern int doingPanel;
+extern int doingVolume;
+extern int screenX;
+extern float xClipMinN, xClipMaxN,
+ yClipMinN, yClipMaxN,
+ zClipMinN, zClipMaxN,
+ clipValue;
+
+extern float pzMin, pzMax;
+
+extern int maxGreyShade;
+
+extern char propertyName[];
+extern char propertyBuffer[];
+
+extern float transform[4][4], transform1[4][4],
+ R[4][4], R1[4][4], S[4][4], T[4][4], I[4][4];
+extern float vxmax,vxmin,vymax,vymin,
+ wxmax,wxmin,wymax,wymin,wzmax,wzmin;
+
+extern polyList *scanList[ARRAY_HEIGHT];
+extern int scanline, polyCount;
+extern float xleft, xright;
+
+extern colorBuffer cBuffer[ARRAY_WIDTH];
+extern float zBuffer[ARRAY_WIDTH];
+
+extern float zC, dzdx;
+extern float intersectColor[2], dcolor;
+extern triple dpt, dnorm;
+
+extern float Cspec, Cdiff, Camb, coeff, lum, saturation;
+
+extern Pixmap viewmap;
+extern int viewmap_valid;
+extern int smoothHue;
+extern int smoothConst;
+extern int smoothError;
+
+extern char *PSfilename; /* output file name in user directory */
+extern char *envAXIOM; /* used for ps file paths */
+
+extern Atom wm_delete_window;
+
diff --git a/src/graph/view3D/header.h b/src/graph/view3D/header.h
new file mode 100755
index 00000000..ca76c7d7
--- /dev/null
+++ b/src/graph/view3D/header.h
@@ -0,0 +1,386 @@
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+
+#define view3D
+
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/Xutil.h>
+#include <setjmp.h>
+
+#include "hash.h"
+
+#include "view.h"
+
+
+#include "view3D.h"
+#include "actions.h"
+#include "viewCommand.h"
+#include "XDefs.h"
+#include "override.h"
+#include "G.h" /* Gdraw functions header file */
+
+#define swap(a,b) {a^=b; b^=a; a^=b;}
+
+ /**********************************/
+ /*** axes stuff ***/
+ /**********************************/
+
+#define viewportCreateMASK CWBackPixel | CWBorderPixel | CWEventMask | CWCursor | CWColormap
+#define viewportTitleCreateMASK CWBackPixel | CWBorderPixel | CWCursor | CWColormap | CWEventMask | CWOverrideRedirect
+#define carefullySetFont(gc,font) if (font != serverFont) XSetFont(dsply,gc,font->fid)
+
+#define viewportMASK (KeyPressMask + ButtonPressMask + ExposureMask)
+#define titleMASK (ExposureMask)
+
+#define lineWidth 1
+#define lineHeight 1
+
+#define titleColor monoColor(36)
+#define titleHeight 24
+#define appendixHeight 0
+
+#define viewWidth 400
+#define viewHeight 400
+#define viewYmax vwInfo.height
+#define viewYmin vwInfo.y
+#define viewXmax vwInfo.width
+#define viewXmin vwInfo.x
+
+#define GC9991 ((GC)9991)
+
+
+/* For smooth shading buffers. Should be screen resolution size,
+ and one for each of screen width and height may be needed, or
+ it can be changed dynamically if desired. */
+
+#ifdef RIOSplatform
+#define ARRAY_WIDTH 1280 + 1 /* DisplayWidth(dsply,scrn) */
+#define ARRAY_HEIGHT 1024 + 1 /* DisplayHeight(dsply,scrn) */
+#else
+#define ARRAY_WIDTH 1300 /* DisplayWidth(dsply,scrn) */
+#define ARRAY_HEIGHT 1100 /* DisplayHeight(dsply,scrn) */
+#endif
+
+#define viewBorderWidth 0 /* make sure ps.h (postscript header) is the same */
+
+#define initDeltaX 0.0
+#define initDeltaY 0.0
+#define initTheta pi_half/2.0
+#define initPhi -pi_half/2.0
+
+#define maxDeltaX 1500.0
+#define maxDeltaY 1500.0
+#define minScale 0.01
+#define maxScale 1000.0
+
+#define rotateFactor 0.2
+#define scaleFactor 0.2
+#define translateFactor 8
+
+#define viewCursorForeground monoColor(166)
+#define viewCursorBackground monoColor(5)
+
+#define axesColor 52
+#define buttonColor 120
+#define labelColor 12
+
+ /**********************************/
+ /*** graph stuff ***/
+ /**********************************/
+
+#define graphBarLeft 76
+#define graphBarTop 180
+#define graphBarWidth graphFont->max_bounds.width + 5
+#define graphBarHeight graphFont->max_bounds.ascent + graphFont->max_bounds.descent
+#define graphBarDefaultColor monoColor(85)
+#define graphBarShowingColor monoColor(45)
+#define graphBarHiddenColor monoColor(146)
+#define graphBarSelectColor monoColor(45)
+#define graphBarNotSelectColor monoColor(145)
+
+ /******************************/
+ /*** colors ***/
+ /******************************/
+
+#define totalHuesConst 27
+
+#define hueEnd 360
+#define hueStep (hueEnd/totalHuesConst)
+
+#define black BlackPixel(dsply,scrn)
+#define white WhitePixel(dsply,scrn)
+#define numPlanes 1
+#define numColors 10
+#define startColor 0
+#define endColor (startColor+numColors)
+#define maxColors (DisplayCells(dsply,scrn)-1)
+#define maxPlanes (DefaultVisual((dpy),(scr))->bits_per_rgb)
+
+#define colorStep ((maxColors+1)/numColors)
+
+ /**********************************/
+ /*** Screen and Window Sizes */
+ /**********************************/
+
+#define physicalWidth DisplayWidth(dsply,scrn)
+#define physicalHeight DisplayHeight(dsply,scrn)
+#define deep DisplayPlanes(dsply,scrn)
+
+#define basicScreen 19
+
+#define yes 1
+#define no 0
+
+#define pi_half 1.57079632
+#define pi 3.14159265
+#define three_pi_halves 4.71238898
+#define two_pi 6.28318530
+#define pi_sq 9.86960440
+
+#define degrees_in_two_pi 57
+#define d2Pi 57
+
+#define nbuckets 128
+
+
+#define anywhere 0
+
+#ifdef DEBUG
+#include "eventnames.h"
+#endif
+
+#define intSize sizeof(int)
+#define floatSize sizeof(float)
+
+/* Types so far are X, PS */
+#define drawViewport(type) { drawPreViewport(type); drawTheViewport(type); }
+#define spadDrawViewport() spadMode++; drawTheViewport(X); spadMode--;
+
+
+ /********************************/
+ /*** lighting panel ***/
+ /********************************/
+
+/* These are the lighting panel buttons, they start at 101
+ (numbers less than 101 are reserved for control panel buttons */
+
+/* From ../include/actions.h */
+
+#define lightingButtonsStart controlButtonsEnd3D
+
+#define lightMove (lightingButtonsStart)
+#define lightMoveXY (lightingButtonsStart+1)
+#define lightMoveZ (lightingButtonsStart+2)
+#define lightAbort (lightingButtonsStart+3)
+#define lightReturn (lightingButtonsStart+4)
+#define lightTranslucent (lightingButtonsStart+5)
+
+#define maxlightingButtons 6
+#define lightingButtonsEnd (lightingButtonsStart + maxlightingButtons)
+
+ /***********************************/
+ /*** view volume panel ***/
+ /***********************************/
+
+/* These are the volume panel buttons, they start at 200
+ (numbers less than 101 are reserved for control panel buttons */
+
+#define volumeButtonsStart lightingButtonsEnd
+
+#define volumeReturn (volumeButtonsStart)
+#define frustrumBut (volumeButtonsStart+1)
+#define clipXBut (volumeButtonsStart+2)
+#define clipYBut (volumeButtonsStart+3)
+#define clipZBut (volumeButtonsStart+4)
+#define perspectiveBut (volumeButtonsStart+5)
+#define clipRegionBut (volumeButtonsStart+6)
+#define clipSurfaceBut (volumeButtonsStart+7)
+#define volumeAbort (volumeButtonsStart+8)
+
+#define maxVolumeButtons 9
+#define volumeButtonsEnd (volumeButtonsStart + maxVolumeButtons)
+
+ /**** quit panel ****/
+
+#define quitButtonsStart volumeButtonsEnd
+
+#define quitAbort (quitButtonsStart)
+#define quitReturn (quitButtonsStart+1)
+#define maxQuitButtons 2
+#define quitButtonsEnd (quitButtonsStart + maxQuitButtons)
+
+ /**** save panel ****/
+
+#define saveButtonsStart quitButtonsEnd
+
+#define saveExit (saveButtonsStart)
+#define pixmap (saveButtonsStart+1)
+#define ps (saveButtonsStart+2)
+#define maxSaveButtons 3
+#define saveButtonsEnd (saveButtonsStart + maxSaveButtons)
+
+ /******************************************/
+ /*** buttons to be allocated ***/
+ /******************************************/
+
+#define maxButtons3D saveButtonsEnd
+
+
+ /************************ Type Declarations *************************/
+
+ /**********************************/
+ /*** control stuff ***/
+ /**********************************/
+
+typedef struct _buttonStruct {
+ int buttonKey, pot, mask;
+ short buttonX, buttonY, buttonWidth, buttonHeight, xHalf, yHalf;
+ Window self;
+ char *text;
+ int textColor,textHue,textShade;
+} buttonStruct;
+
+typedef struct _controlPanelStruct {
+ Window controlWindow, messageWindow, colormapWindow;
+ char message[40];
+ buttonStruct buttonQueue[maxButtons3D];
+} controlPanelStruct;
+
+typedef struct _mouseCoord {
+ float x, y;
+} mouseCoord;
+
+
+ /**********************************/
+ /*** mesh stuff ***/
+ /**********************************/
+
+typedef struct _meshStruct {
+ float N0[4], N1[4]; /* the fourth element is Zmin */
+} meshStruct;
+
+typedef struct _points3D {
+ float xmin, xmax,
+ ymin, ymax,
+ xstep, ystep,
+ zmin, zmax,
+ scaleToView;
+ float *zPoints;
+ int xnum, ynum,
+ nextRow,
+ style;
+ meshStruct *normData; /* list of normals */
+} points3D;
+
+
+
+typedef struct _colorBuffer {
+ int indx;
+ char axes;
+} colorBuffer;
+
+
+ /**********************************/
+ /*** axes stuff ***/
+ /**********************************/
+
+typedef struct _point {
+ float x, y, z;
+ int flag;
+} point;
+
+
+ /**** one of the (many) sloppy things that need to be
+ cleaned up is the viewPoints structure. a lot of
+ stuff in it is used solely for the function of
+ two variables stuff. they should be moved to
+ the fun2Var substructure. ****/
+
+typedef struct _viewPoints {
+ int viewportKey;
+ char title[80];
+ Window viewWindow, titleWindow;
+ float deltaX, deltaY,
+ scale, scaleX, scaleY, scaleZ,
+ theta, phi,
+ deltaX0, deltaY0, /* initial values */
+ scale0, transX, transY, transZ, thetaObj, phiObj,
+ theta0, phi0, theta1, phi1, axestheta, axesphi;
+ float deltaZ, deltaZ0;
+ controlPanelStruct *controlPanel;
+ int axesOn, regionOn, monoOn;
+ int zoomXOn, zoomYOn, zoomZOn;
+ int originrOn, objectrOn;
+ int xyOn, xzOn, yzOn;
+ int originFlag;
+ int justMadeControl, haveControl,
+ closing, allowDraw, needNorm;
+ points3D meshData;
+ float lightVector[3], translucency;
+ int hueOffset, numberOfHues, hueTop, diagonals;
+ struct _viewPoints *prevViewport, *nextViewport;
+} viewPoints;
+
+
+typedef struct _controlXY {
+ int putX, putY;
+} controlXY;
+
+
+
+ /************************** Bitmap Files ***************************/
+#if 0
+#include "../include/purty/mouse11.bitmap"
+#include "../include/purty/mouse11.mask"
+#include "../include/purty/spadBitmap.bitmap"
+#include "../include/purty/spadMask.mask"
+#include "../include/purty/light11.bitmap"
+#include "../include/purty/light11.mask"
+#endif
+
+
+ /******* useful definitions *******/
+
+#define CONTROLpanel 1
+#define LIGHTpanel 2
+#define VOLUMEpanel 3
+#define CONTOURpanel 4
+#define QUITpanel 5
+#define SAVEpanel 6
+
+#define machine0 0.0002
+
+#include "globals.h"
+
diff --git a/src/graph/view3D/illuminate3d.c.pamphlet b/src/graph/view3D/illuminate3d.c.pamphlet
new file mode 100644
index 00000000..686ded74
--- /dev/null
+++ b/src/graph/view3D/illuminate3d.c.pamphlet
@@ -0,0 +1,237 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D illuminate3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _ILLUMINATE3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+
+#include <math.h>
+
+#include "header.h"
+#include "draw.h"
+
+#include "all_3d.H1"
+
+/***********************
+ * void phong(pt,N) *
+ * *
+ * a general routine *
+ * for determining the *
+ * intensity values at *
+ * a particular point *
+ * using the Phong *
+ * illumination model *
+ * with Phong shading *
+ ***********************/
+
+float
+#ifdef _NO_PROTO
+phong(pt,N)
+ triple pt;
+ float N[3];
+#else
+phong(triple pt,float N[3])
+#endif
+{
+ float dotLN, dotHN, H[3], E[3], P[3], NM[3], L[3];
+ float color, diffuse, specular;
+
+ diffuse = 0.0; specular = 0.0;
+
+ /* renormalize average normal vector for the point */
+ normalizeVector(N);
+ /* temporary norm, in case the sign is switched */
+ NM[0] = N[0]; NM[1] = N[1]; NM[2] = N[2];
+
+ P[0] = pt.x; P[1] = pt.y; P[2] = pt.z;
+ normalizeVector(P);
+
+ /* vector from infinite light source */
+ L[0] = viewport->lightVector[0];
+ L[1] = viewport->lightVector[1];
+ L[2] = viewport->lightVector[2];
+ normalizeVector(L);
+
+ /* vector from point to observers eye */
+ normalizeVector(eyePoint);
+ E[0] = 8.0*eyePoint[0] - P[0];
+ E[1] = 8.0*eyePoint[1] - P[1];
+ E[2] = 8.0*eyePoint[2] - P[2];
+ normalizeVector(E);
+
+ /* light returned even if normal faces away from light source */
+ dotLN = L[0]*NM[0] + L[1]*NM[1] + L[2]*NM[2];
+ if (dotLN < 0.0) dotLN = -dotLN;
+ diffuse = dotLN*lightIntensity;
+ /* calculate specular highlight if surface faces light source */
+ if (dotLN > 0.0) {
+ H[0] = E[0] + L[0];
+ H[1] = E[1] + L[1];
+ H[2] = E[2] + L[2];
+ normalizeVector(H);
+ dotHN = NM[0]*H[0]+NM[1]*H[1]+NM[2]*H[2];
+ if (dotHN < 0.0) dotHN = -dotHN;
+ specular = pow((double)dotHN,coeff)*lightIntensity;
+ }
+
+ /* return intensity value from 0.0 to 1.0 */
+ color = Camb + diffuse*Cdiff + specular*Cspec;
+
+ if (color > 1.0) color = 1.0;
+ if (color < 0.0) color = 0.0;
+
+ return(color);
+}
+
+int
+#ifdef _NO_PROTO
+hueValue(val)
+ float val;
+#else
+hueValue(float val)
+#endif
+{
+ int hue;
+
+ hue = floor(absolute(val) * viewport->numberOfHues) + viewport->hueOffset;
+ if (hue > 26) hue = 26;
+
+ return hue;
+}
+
+int
+#ifdef _NO_PROTO
+getHue(val)
+ float val;
+#else
+getHue(float val)
+#endif
+{
+ int hue;
+
+ hue = hueValue(val);
+ if (hue < 11)
+ hue *= 6;
+ else
+ if (hue > 10 && hue < 16)
+ hue = hue*20 - 140;
+ else
+ hue = hue*12 - 12;
+
+ return hue;
+}
+
+/**** Conversion functions for different color models ****/
+
+float
+#ifdef _NO_PROTO
+Value(n1, n2, hue)
+ float n1, n2, hue;
+#else
+Value(float n1, float n2, float hue)
+#endif
+{
+ float v;
+
+ if (hue > 360.0) hue -= 360.0;
+ if (hue < 0.0) hue += 360.0;
+ if (hue < 60.0) {
+ v = n1 + (n2-n1)*hue/60.0;
+ } else {
+ if (hue < 180.0) {
+ v = n2;
+ } else {
+ if (hue < 240.0) {
+ v = n1 + (n2-n1)*(240.0-hue)/60.0;
+ } else {
+ v = n1;
+ }
+ }
+ }
+ return(v);
+}
+
+
+RGB
+#ifdef _NO_PROTO
+hlsTOrgb(h,l,s)
+ float h, l, s;
+#else
+hlsTOrgb(float h,float l,float s)
+#endif
+{
+ RGB rgb;
+ float m1, m2;
+
+ if (l <= 0.5) {
+ m2 = l*(1.0+s);
+ }
+ else {
+ m2 = l+s-l*s;
+ }
+ m1 = 2.0*l-m2;
+ rgb.r = Value(m1,m2,h+120.0);
+ rgb.g = Value(m1,m2,h);
+ rgb.b = Value(m1,m2,h-120.0);
+
+ return(rgb);
+}
+
+
+
+
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/lightbut3d.c.pamphlet b/src/graph/view3D/lightbut3d.c.pamphlet
new file mode 100644
index 00000000..4543927a
--- /dev/null
+++ b/src/graph/view3D/lightbut3d.c.pamphlet
@@ -0,0 +1,173 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D lightbut3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _LIGHTBUT3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include "header.h"
+#include "cpanel.h"
+
+#include "all_3d.H1"
+/*****************************************************
+ * int initLightButtons (lightButtons) *
+ * *
+ * Creates the fields for each button window in the *
+ * three dimensional lighting subpanel, and returns *
+ * the number of buttons created. *
+ * *
+ *****************************************************/
+
+int
+#ifdef _NO_PROTO
+initLightButtons (lightButtons)
+ buttonStruct *lightButtons;
+#else
+initLightButtons (buttonStruct *lightButtons)
+#endif
+{
+ int ii;
+ int num = 0;
+
+ /* Not functional -- can be used to allow light window as a potentiometer */
+ ii = lightMove;
+ lightButtons[ii].buttonX = 63;
+ lightButtons[ii].buttonY = 30;
+ lightButtons[ii].buttonWidth = 171;
+ lightButtons[ii].buttonHeight = 171;
+ lightButtons[ii].buttonKey = ii;
+ lightButtons[ii].pot = yes; /* a potentiometer */
+ lightButtons[ii].mask = potMASK;
+ lightButtons[ii].textColor = 163;
+ lightButtons[ii].xHalf = lightButtons[ii].buttonWidth/2;
+ lightButtons[ii].yHalf = lightButtons[ii].buttonHeight/2;
+ ++num;
+
+ /* Change x and y coordinate of light source */
+ ii = lightMoveXY;
+ lightButtons[ii].buttonX = 20;
+ lightButtons[ii].buttonY = 247;
+ lightButtons[ii].buttonWidth = 110;
+ lightButtons[ii].buttonHeight = 110;
+ lightButtons[ii].buttonKey = ii;
+ lightButtons[ii].pot = yes; /* a potentiometer */
+ lightButtons[ii].mask = potMASK;
+ lightButtons[ii].textColor = 133;
+ lightButtons[ii].xHalf = lightButtons[ii].buttonWidth/2;
+ lightButtons[ii].yHalf = lightButtons[ii].buttonHeight/2;
+ ++num;
+
+ /* Change z coordinate of light source */
+ ii = lightMoveZ;
+ lightButtons[ii].buttonX = 149;
+ lightButtons[ii].buttonY = 247;
+ lightButtons[ii].buttonWidth = 58;
+ lightButtons[ii].buttonHeight = 110;
+ lightButtons[ii].buttonKey = ii;
+ lightButtons[ii].pot = yes; /* a potentiometer */
+ lightButtons[ii].mask = potMASK;
+ lightButtons[ii].textColor = 165;
+ lightButtons[ii].xHalf = lightButtons[ii].buttonWidth/2;
+ lightButtons[ii].yHalf = lightButtons[ii].buttonHeight/2;
+ ++num;
+
+ /* Change intensity of light source */
+ ii = lightTranslucent;
+ lightButtons[ii].buttonX = 250;
+ lightButtons[ii].buttonY = 247;
+ lightButtons[ii].buttonWidth = 34;
+ lightButtons[ii].buttonHeight = 110;
+ lightButtons[ii].buttonKey = ii;
+ lightButtons[ii].pot = yes; /* a potentiometer */
+ lightButtons[ii].mask = potMASK;
+ lightButtons[ii].textColor = 37;
+ lightButtons[ii].xHalf = lightButtons[ii].buttonWidth/2;
+ lightButtons[ii].yHalf = lightButtons[ii].buttonHeight/2;
+ ++num;
+
+ /* Leave lighting window without updating changes made. */
+ ii = lightAbort;
+ lightButtons[ii].buttonX = 36;
+ lightButtons[ii].buttonY = 370;
+ lightButtons[ii].buttonWidth = 110;
+ lightButtons[ii].buttonHeight = 24;
+ lightButtons[ii].buttonKey = ii;
+ lightButtons[ii].pot = no;
+ lightButtons[ii].mask = buttonMASK;
+ lightButtons[ii].text = "Abort";
+ lightButtons[ii].textColor = 52;
+ lightButtons[ii].xHalf = lightButtons[ii].buttonWidth/2;
+ lightButtons[ii].yHalf = lightButtons[ii].buttonHeight/2;
+ ++num;
+
+ /* Leave lighting window and update changes made. */
+ ii = lightReturn;
+ lightButtons[ii].buttonX = 154;
+ lightButtons[ii].buttonY = 370;
+ lightButtons[ii].buttonWidth = 110;
+ lightButtons[ii].buttonHeight = 24;
+ lightButtons[ii].buttonKey = ii;
+ lightButtons[ii].pot = no;
+ lightButtons[ii].mask = buttonMASK;
+ lightButtons[ii].text = "Return";
+ lightButtons[ii].textColor = 28;
+ lightButtons[ii].xHalf = lightButtons[ii].buttonWidth/2;
+ lightButtons[ii].yHalf = lightButtons[ii].buttonHeight/2;
+ ++num;
+
+ return(num);
+}
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/lighting3d.c.pamphlet b/src/graph/view3D/lighting3d.c.pamphlet
new file mode 100644
index 00000000..0719c4b3
--- /dev/null
+++ b/src/graph/view3D/lighting3d.c.pamphlet
@@ -0,0 +1,628 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D lighting3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _LIGHTING3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include <math.h>
+#include <string.h>
+
+#include "light11.bitmap"
+#include "light11.mask"
+
+
+#include "header.h"
+#include "static.h"
+#include "draw.h"
+#include "cpanel.h"
+#include "volume.h"
+
+#include "Gfun.H1"
+#include "XSpadFill.H1"
+#include "all_3d.H1"
+
+#define lightMASK ExposureMask
+#define lightCursorForeground lightingTitleColor
+#define lightCursorBackground foregroundColor
+
+#define lightFontHeight (lightingFont->max_bounds.ascent+lightingFont->max_bounds.descent)
+
+#define lightingAxesColor monoColor(52)
+#define lightingLabelColor monoColor(12)
+#define lightingBoxColor monoColor(138)
+#define lightingLightColor monoColor(7)
+#define lightingTitleColor monoColor(69)
+#define lightingButtonColor monoColor(140)
+#define lightingTransColor monoColor(140)
+#define lightingTransArrowColor monoColor(100)
+#define lightingTransLabelColor monoColor(207)
+
+#define lightingAxesSize 175
+#define lightingAxesX 61
+#define lightingAxesY 28
+
+#define lightAxesScale 110 /* the extent of the axes in object space */
+#define lightScale 0.63 /* projected scale factor */
+
+#define arrowHead (control->buttonQueue[lightTranslucent].buttonX + 5)
+static viewTriple point0 = {0,0,0};
+
+
+/***************************
+ * int makeLightingPanel() *
+ ***************************/
+
+int
+#ifdef _NO_PROTO
+makeLightingPanel()
+#else
+makeLightingPanel(void)
+#endif
+{
+
+ int i;
+ XSetWindowAttributes cwAttrib, controlAttrib;
+ XSizeHints sizehint;
+ Pixmap lightbits,lightmask;
+ XColor foreColor, backColor;
+
+ lightbits = XCreateBitmapFromData(dsply,rtWindow, lightBitmap_bits,
+ lightBitmap_width,lightBitmap_height);
+ lightmask = XCreateBitmapFromData(dsply,rtWindow, lightMask_bits,
+ lightMask_width,lightMask_height);
+ cwAttrib.background_pixel = backgroundColor;
+ cwAttrib.border_pixel = foregroundColor;
+ cwAttrib.event_mask = lightMASK;
+ cwAttrib.colormap = colorMap;
+ cwAttrib.override_redirect = overrideManager;
+ foreColor.pixel = lightCursorForeground;
+ XQueryColor(dsply,colorMap,&foreColor);
+ backColor.pixel = lightCursorBackground;
+ XQueryColor(dsply,colorMap,&backColor);
+ cwAttrib.cursor = XCreatePixmapCursor(dsply,lightbits,lightmask,
+ &foreColor,&backColor,
+ lightBitmap_x_hot,lightBitmap_y_hot);
+ lightingWindow = XCreateWindow(dsply,control->controlWindow,
+ -3,-3,controlWidth,controlHeight,3,
+ CopyFromParent,InputOutput,CopyFromParent,
+ controlCreateMASK,&cwAttrib);
+
+ sizehint.flags = USPosition | USSize;
+ sizehint.x = 0;
+ sizehint.y = 0;
+ sizehint.width = controlWidth;
+ sizehint.height = controlHeight;
+ /*** the None stands for icon pixmap. ***/
+ XSetNormalHints(dsply,lightingWindow,&sizehint);
+ XSetStandardProperties(dsply,lightingWindow,"Lighting Panel 3D",
+ "Lighting Panel",None,NULL,0,&sizehint);
+
+ /*** lighting axes window ***/
+ cwAttrib.event_mask = 0;
+ lightingAxes = XCreateWindow(dsply,lightingWindow,
+ lightingAxesX,lightingAxesY,
+ lightingAxesSize,lightingAxesSize,
+ 0,CopyFromParent,InputOutput,CopyFromParent,
+ controlCreateMASK,&cwAttrib);
+
+ sizehint.flags = USPosition | USSize;
+ sizehint.x = lightingAxesX;
+ sizehint.y = lightingAxesY;
+ sizehint.width = lightingAxesSize;
+ sizehint.height = lightingAxesSize;
+ /*** the None stands for icon pixmap ***/
+ XSetNormalHints(dsply,lightingAxes,&sizehint);
+ XSetStandardProperties(dsply,lightingAxes,"Lighting Axes","Lighting Axes",
+ None,NULL,0,&sizehint);
+ XMapWindow(dsply,lightingAxes);
+
+ /*** draw lighting buttons ***/
+ initLightButtons(control->buttonQueue);
+/*
+ controlAttrib.event_mask = (control->buttonQueue[lightingButtonsStart]).mask;
+ (control->buttonQueue[lightingButtonsStart]).self =
+ XCreateWindow(dsply, lightingWindow,
+ (control->buttonQueue[lightingButtonsStart]).buttonX,
+ (control->buttonQueue[lightingButtonsStart]).buttonY,
+ (control->buttonQueue[lightingButtonsStart]).buttonWidth,
+ (control->buttonQueue[lightingButtonsStart]).buttonHeight,
+ 0,0,InputOnly,CopyFromParent,
+ buttonCreateMASK,&controlAttrib);
+ XMakeAssoc(dsply,table,(control->buttonQueue[lightingButtonsStart]).self,
+ &((control->buttonQueue[lightingButtonsStart]).buttonKey));
+ XMapWindow(dsply,(control->buttonQueue[lightingButtonsStart]).self);
+*/
+ for (i=(lightingButtonsStart + 1); i<(lightingButtonsEnd); i++) {
+ controlAttrib.event_mask = (control->buttonQueue[i]).mask;
+ (control->buttonQueue[i]).self =
+ XCreateWindow(dsply,lightingWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,
+ 0,0,InputOnly,CopyFromParent,
+ buttonCreateMASK,&controlAttrib);
+ XMakeAssoc(dsply,table,(control->buttonQueue[i]).self,
+ &((control->buttonQueue[i]).buttonKey));
+ XMapWindow(dsply,(control->buttonQueue[i]).self);
+ }
+
+ /* assign global direction variables for light projections */
+ sinTheta = sin(-viewport->theta);
+ cosTheta = cos(-viewport->theta);
+ sinPhi = sin(viewport->phi);
+ cosPhi = cos(viewport->phi);
+
+ return(0);
+
+} /* makeLightingPanel() */
+
+/***************************
+ * void drawLightingAxes() *
+ ***************************/
+
+void
+#ifdef _NO_PROTO
+drawLightingAxes()
+#else
+drawLightingAxes(void)
+#endif
+{
+
+ XWindowAttributes laInfo;
+ int i,xCenter,yCenter;
+ float Px0,Py0;
+ int vPx0,vPy0,vPx1,vPy1;
+ viewTriple pointX,pointY,pointXY,pointXYZ;
+
+ XGetWindowAttributes(dsply,lightingAxes,&laInfo);
+ XClearWindow(dsply,lightingAxes);
+ xCenter = laInfo.width / 2;
+ yCenter = laInfo.height / 2;
+
+ sinTheta = sin(-viewport->theta);
+ cosTheta = cos(-viewport->theta);
+ sinPhi = sin(viewport->phi);
+ cosPhi = cos(viewport->phi);
+
+ GSetForeground(lightingGC,(float)monoColor(buttonColor),Xoption);
+ for (i=0; i < 3; i++) {
+ Px0 = proj2PX(axes[i][0],axes[i][1]);
+ Py0 = proj2PY(axes[i][0],axes[i][1],axes[i][2]);
+ vPx0 = Px0 * lightScale + xCenter;
+ vPy0 = laInfo.height - (Py0 * lightScale + yCenter);
+ Px0 = proj2PX(axes[i][3],axes[i][4]);
+ Py0 = proj2PY(axes[i][3],axes[i][4],axes[i][5]);
+ vPx1 = Px0 * lightScale + xCenter;
+ vPy1 = laInfo.height - (Py0 * lightScale + yCenter);
+ GDrawLine(lightingGC,lightingAxes,vPx0,vPy0,vPx1,vPy1,Xoption);
+ }
+
+ GSetForeground(lightingGC,(float)lightingLabelColor,Xoption);
+ for (i=0; i < basicScreen; i++) {
+ Px0 = proj2PX(labels[i][0],labels[i][1]);
+ Py0 = proj2PY(labels[i][0],labels[i][1],labels[i][2]);
+ vPx0 = Px0 * lightScale + xCenter;
+ vPy0 = laInfo.height - (Py0 * lightScale + yCenter);
+ Px0 = proj2PX(labels[i][3],labels[i][4]);
+ Py0 = proj2PY(labels[i][3],labels[i][4],labels[i][5]);
+ vPx1 = Px0 * lightScale + xCenter;
+ vPy1 = laInfo.height - (Py0 * lightScale + yCenter);
+ GDrawLine(lightingGC,lightingAxes,vPx0,vPy0,vPx1,vPy1,Xoption);
+ }
+
+ GSetForeground(lightingGC,(float)lightingBoxColor,Xoption);
+ pointX.x = tempLightPointer[0] * lightAxesScale;
+ pointX.y = 0;
+ pointX.z = 0;
+
+ pointY.x = 0;
+ pointY.y = tempLightPointer[1] * lightAxesScale;
+ pointY.z = 0;
+
+ pointXY.x = tempLightPointer[0] * lightAxesScale;
+ pointXY.y = tempLightPointer[1] * lightAxesScale;
+ pointXY.z = 0;
+
+ pointXYZ.x = tempLightPointer[0] * lightAxesScale;
+ pointXYZ.y = tempLightPointer[1] * lightAxesScale;
+ pointXYZ.z = tempLightPointer[2] * lightAxesScale;
+
+ Px0 = proj2PX(pointXY.x,pointXY.y);
+ Py0 = proj2PY(pointXY.x,pointXY.y,pointXY.z);
+ vPx0 = Px0 * lightScale + xCenter;
+ vPy0 = laInfo.height - (Py0 * lightScale + yCenter);
+
+ Px0 = proj2PX(pointX.x,pointX.y);
+ Py0 = proj2PY(pointX.x,pointX.y,pointX.z);
+ vPx1 = Px0 * lightScale + xCenter;
+ vPy1 = laInfo.height - (Py0 * lightScale + yCenter);
+ GDrawLine(lightingGC,lightingAxes,vPx0,vPy0,vPx1,vPy1,Xoption);
+
+ Px0 = proj2PX(pointY.x,pointY.y);
+ Py0 = proj2PY(pointY.x,pointY.y,pointY.z);
+ vPx1 = Px0 * lightScale + xCenter;
+ vPy1 = laInfo.height - (Py0 * lightScale + yCenter);
+ GDrawLine(lightingGC,lightingAxes,vPx0,vPy0,vPx1,vPy1,Xoption);
+
+ Px0 = proj2PX(pointXYZ.x,pointXYZ.y);
+ Py0 = proj2PY(pointXYZ.x,pointXYZ.y,pointXYZ.z);
+ vPx1 = Px0 * lightScale + xCenter;
+ vPy1 = laInfo.height - (Py0 * lightScale + yCenter);
+ GDrawLine(lightingGC,lightingAxes,vPx0,vPy0,vPx1,vPy1,Xoption);
+
+ GSetForeground(lightingGC,(float)lightingLightColor,Xoption);
+ Px0 = proj2PX(point0.x,point0.y);
+ Py0 = proj2PY(point0.x,point0.y,point0.z);
+ vPx0 = Px0 * lightScale + xCenter;
+ vPy0 = laInfo.height - (Py0 * lightScale + yCenter);
+ GDrawLine(lightingGC,lightingAxes,vPx0,vPy0,vPx1,vPy1,Xoption);
+
+} /* drawLightingAxes */
+
+
+/******************************
+ * void drawLightTransArrow() *
+ ******************************/
+
+void
+#ifdef _NO_PROTO
+drawLightTransArrow()
+#else
+drawLightTransArrow(void)
+#endif
+{
+
+ int i;
+ float f;
+
+ /*** Draw the intensity potentiometer window. ***/
+ XClearArea(dsply,lightingWindow,
+ (control->buttonQueue[lightTranslucent]).buttonX,
+ (control->buttonQueue[lightTranslucent]).buttonY-5,
+ (control->buttonQueue[lightTranslucent]).buttonWidth,
+ (control->buttonQueue[lightTranslucent]).buttonHeight+10,
+ False);
+ GDrawLine(controlMessageGC,lightingWindow,
+ (control->buttonQueue[lightTranslucent]).buttonX,
+ (control->buttonQueue[lightTranslucent]).buttonY,
+ (control->buttonQueue[lightTranslucent]).buttonX,
+ (control->buttonQueue[lightTranslucent]).buttonY +
+ (control->buttonQueue[lightTranslucent]).buttonHeight,Xoption);
+ GDrawLine(controlMessageGC,lightingWindow,
+ (control->buttonQueue[lightTranslucent]).buttonX + 1,
+ (control->buttonQueue[lightTranslucent]).buttonY,
+ (control->buttonQueue[lightTranslucent]).buttonX +
+ (control->buttonQueue[lightTranslucent]).buttonWidth * 3/10,
+ (control->buttonQueue[lightTranslucent]).buttonY,Xoption);
+ GDrawLine(controlMessageGC,lightingWindow,
+ (control->buttonQueue[lightTranslucent]).buttonX + 1,
+ (control->buttonQueue[lightTranslucent]).buttonY +
+ (control->buttonQueue[lightTranslucent]).yHalf/2,
+ (control->buttonQueue[lightTranslucent]).buttonX +
+ (control->buttonQueue[lightTranslucent]).buttonWidth * 2/10,
+ (control->buttonQueue[lightTranslucent]).buttonY +
+ (control->buttonQueue[lightTranslucent]).yHalf/2,Xoption);
+ GDrawLine(controlMessageGC,lightingWindow,
+ (control->buttonQueue[lightTranslucent]).buttonX + 1,
+ (control->buttonQueue[lightTranslucent]).buttonY +
+ (control->buttonQueue[lightTranslucent]).yHalf,
+ (control->buttonQueue[lightTranslucent]).buttonX +
+ (control->buttonQueue[lightTranslucent]).buttonWidth * 3/10,
+ (control->buttonQueue[lightTranslucent]).buttonY +
+ (control->buttonQueue[lightTranslucent]).yHalf,Xoption);
+ GDrawLine(controlMessageGC,lightingWindow,
+ (control->buttonQueue[lightTranslucent]).buttonX + 1,
+ (control->buttonQueue[lightTranslucent]).buttonY +
+ (control->buttonQueue[lightTranslucent]).buttonHeight*3/4,
+ (control->buttonQueue[lightTranslucent]).buttonX +
+ (control->buttonQueue[lightTranslucent]).buttonWidth * 2/10,
+ (control->buttonQueue[lightTranslucent]).buttonY +
+ (control->buttonQueue[lightTranslucent]).buttonHeight*3/4,Xoption);
+ GDrawLine(controlMessageGC,lightingWindow,
+ (control->buttonQueue[lightTranslucent]).buttonX + 1,
+ (control->buttonQueue[lightTranslucent]).buttonY +
+ (control->buttonQueue[lightTranslucent]).buttonHeight,
+ (control->buttonQueue[lightTranslucent]).buttonX +
+ (control->buttonQueue[lightTranslucent]).buttonWidth * 3/10,
+ (control->buttonQueue[lightTranslucent]).buttonY +
+ (control->buttonQueue[lightTranslucent]).buttonHeight,Xoption);
+
+ /*** Draw the intensity selection arrow ***/
+ GSetForeground(lightingGC,(float)lightingTransArrowColor,Xoption);
+
+ f = (control->buttonQueue[lightTranslucent].buttonY +
+ control->buttonQueue[lightTranslucent].buttonHeight) -
+ (tempLightIntensity *
+ control->buttonQueue[lightTranslucent].buttonHeight);
+ i = f;
+ GDrawLine(lightingGC, lightingWindow, arrowHead + 10, i,
+ arrowHead + 22, i + 2, Xoption);
+ GDrawLine(lightingGC, lightingWindow, arrowHead + 22, i + 2,
+ arrowHead + 22, i - 2, Xoption);
+ GDrawLine(lightingGC, lightingWindow, arrowHead + 22, i - 2,
+ arrowHead + 10, i, Xoption);
+
+} /* drawLightTransArrow() */
+
+
+
+
+
+/****************************
+ * void drawLightingPanel() *
+ ****************************/
+
+void
+#ifdef _NO_PROTO
+drawLightingPanel()
+#else
+drawLightingPanel(void)
+#endif
+{
+
+ char *s;
+ int i,strlength;
+
+ /* Draw border lines to separate the lighting window, potentiometers,
+ and button regions of the lightng subpanel. */
+ GSetForeground(trashGC,(float)foregroundColor,Xoption);
+ GSetLineAttributes(trashGC,3,LineSolid,CapButt,JoinMiter,Xoption);
+ GDrawLine(trashGC, lightingWindow, 0, potA, controlWidth, potA, Xoption);
+
+ GSetLineAttributes(trashGC,2,LineSolid,CapButt,JoinMiter,Xoption);
+ GDrawLine(trashGC, lightingWindow, 0, lightB, controlWidth, lightB, Xoption);
+ GDrawLine(trashGC, lightingWindow, 0, lightPotA, controlWidth,
+ lightPotA, Xoption);
+ GDrawLine(trashGC, lightingWindow, 0, lightPotB, controlWidth,
+ lightPotB, Xoption);
+ GDrawLine(trashGC, lightingWindow, lightTransL, lightPotA,
+ lightTransL, lightPotB, Xoption);
+
+ writeControlTitle(lightingWindow);
+ s = "Lighting Control Panel";
+ strlength = strlen(s);
+ GSetForeground(anotherGC,(float)lightingTitleColor,Xoption);
+ GDrawString(anotherGC, lightingWindow,
+ centerX(anotherGC, s, strlength, controlWidth),
+ lightB+18, s, strlength, Xoption);
+
+ for (i=lightingButtonsStart; i<(lightingButtonsEnd); i++) {
+ switch (i) {
+ case lightMove:
+ GSetForeground(lightingGC,(float)lightingButtonColor,Xoption);
+ GDraw3DButtonOut(lightingGC,lightingWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,Xoption);
+ GSetForeground(lightingGC,(float)monoColor(buttonColor),Xoption);
+ GDrawLine(lightingGC,lightingWindow,
+ (control->buttonQueue[i]).buttonX +
+ (control->buttonQueue[i]).xHalf,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonX +
+ (control->buttonQueue[i]).xHalf,
+ (control->buttonQueue[i]).buttonY +
+ 2*(control->buttonQueue[i]).yHalf,Xoption);
+ GDrawLine(lightingGC,lightingWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY +
+ (control->buttonQueue[i]).yHalf,
+ (control->buttonQueue[i]).buttonX +
+ 2*(control->buttonQueue[i]).xHalf,
+ (control->buttonQueue[i]).buttonY +
+ (control->buttonQueue[i]).yHalf,Xoption);
+ break;
+ case lightMoveXY:
+ GSetForeground(lightingGC,(float)lightingButtonColor,Xoption);
+ GDraw3DButtonOut(lightingGC,lightingWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,Xoption);
+ GSetForeground(lightingGC,(float)monoColor(buttonColor),Xoption);
+ GDrawLine(lightingGC,lightingWindow,
+ (control->buttonQueue[i]).buttonX +
+ (control->buttonQueue[i]).xHalf,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonX +
+ (control->buttonQueue[i]).xHalf,
+ (control->buttonQueue[i]).buttonY +
+ 2*(control->buttonQueue[i]).yHalf,Xoption);
+ GDrawLine(lightingGC,lightingWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY +
+ (control->buttonQueue[i]).yHalf,
+ (control->buttonQueue[i]).buttonX +
+ 2*(control->buttonQueue[i]).xHalf,
+ (control->buttonQueue[i]).buttonY +
+ (control->buttonQueue[i]).yHalf,Xoption);
+ break;
+ case lightMoveZ:
+ GSetForeground(lightingGC,(float)lightingButtonColor,Xoption);
+ GDraw3DButtonOut(lightingGC,lightingWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,Xoption);
+ GSetForeground(lightingGC,(float)monoColor(buttonColor),Xoption);
+ GDrawLine(lightingGC,lightingWindow,
+ (control->buttonQueue[i]).buttonX +
+ (control->buttonQueue[i]).xHalf,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonX +
+ (control->buttonQueue[i]).xHalf,
+ (control->buttonQueue[i]).buttonY +
+ 2*(control->buttonQueue[i]).yHalf,Xoption);
+ GDrawLine(lightingGC,lightingWindow,
+ (control->buttonQueue[i]).buttonX +
+ (control->buttonQueue[i]).xHalf -
+ (control->buttonQueue[i]).xHalf/2,
+ (control->buttonQueue[i]).buttonY +
+ (control->buttonQueue[i]).yHalf,
+ (control->buttonQueue[i]).buttonX +
+ (control->buttonQueue[i]).xHalf +
+ (control->buttonQueue[i]).xHalf/2,
+ (control->buttonQueue[i]).buttonY +
+ (control->buttonQueue[i]).yHalf,Xoption);
+ break;
+ case lightTranslucent:
+ drawLightTransArrow();
+ break;
+ default:
+ GDraw3DButtonOut(lightingGC,lightingWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,Xoption);
+ s = (control->buttonQueue[i]).text;
+ strlength = strlen(s);
+ GSetForeground(trashGC,
+ (float)monoColor((control->buttonQueue[i]).textColor),Xoption);
+ GDrawString(trashGC, lightingWindow,
+ (control->buttonQueue[i]).buttonX +
+ centerX(processGC,s,strlength,
+ (control->buttonQueue[i]).buttonWidth),
+ (control->buttonQueue[i]).buttonY +
+ centerY(processGC,(control->buttonQueue[i]).buttonHeight),
+ s,strlen(s),Xoption);
+ } /* switch */
+ } /* for i in control->buttonQueue */
+
+ GSetForeground(lightingGC,(float)monoColor(labelColor),Xoption);
+ GDrawString(lightingGC,lightingWindow,
+ control->buttonQueue[lightMoveXY].buttonX +
+ control->buttonQueue[lightMoveXY].buttonWidth + 3,
+ control->buttonQueue[lightMoveXY].buttonY +
+ control->buttonQueue[lightMoveXY].yHalf,
+ "x",1,Xoption);
+ GDrawString(lightingGC,lightingWindow,
+ control->buttonQueue[lightMoveXY].buttonX +
+ control->buttonQueue[lightMoveXY].xHalf - 2,
+ control->buttonQueue[lightMoveXY].buttonY - 4,
+ "y",1,Xoption);
+ GDrawString(lightingGC,lightingWindow,
+ control->buttonQueue[lightMoveZ].buttonX +
+ control->buttonQueue[lightMoveZ].xHalf - 2,
+ control->buttonQueue[lightMoveZ].buttonY - 4,
+ "z",1,Xoption);
+
+ /** Draw the title for the intensity potentiometer. */
+ GSetForeground(lightingGC,(float)lightingTransColor,Xoption);
+
+ GDrawString(lightingGC,lightingWindow,
+ control->buttonQueue[lightTranslucent].buttonX +
+ control->buttonQueue[lightTranslucent].buttonWidth + 3,
+ control->buttonQueue[lightTranslucent].buttonY,
+ "I",1,Xoption);
+ GDrawString(lightingGC,lightingWindow,
+ control->buttonQueue[lightTranslucent].buttonX +
+ control->buttonQueue[lightTranslucent].buttonWidth + 3,
+ control->buttonQueue[lightTranslucent].buttonY +
+ lightFontHeight,
+ "n",1,Xoption);
+ GDrawString(lightingGC,lightingWindow,
+ control->buttonQueue[lightTranslucent].buttonX +
+ control->buttonQueue[lightTranslucent].buttonWidth + 3,
+ control->buttonQueue[lightTranslucent].buttonY +
+ lightFontHeight*2,
+ "t",1,Xoption);
+ GDrawString(lightingGC,lightingWindow,
+ control->buttonQueue[lightTranslucent].buttonX +
+ control->buttonQueue[lightTranslucent].buttonWidth + 3,
+ control->buttonQueue[lightTranslucent].buttonY +
+ lightFontHeight*3,
+ "e",1,Xoption);
+ GDrawString(lightingGC,lightingWindow,
+ control->buttonQueue[lightTranslucent].buttonX +
+ control->buttonQueue[lightTranslucent].buttonWidth + 3,
+ control->buttonQueue[lightTranslucent].buttonY +
+ lightFontHeight*4,
+ "n",1,Xoption);
+ GDrawString(lightingGC,lightingWindow,
+ control->buttonQueue[lightTranslucent].buttonX +
+ control->buttonQueue[lightTranslucent].buttonWidth + 3,
+ control->buttonQueue[lightTranslucent].buttonY +
+ lightFontHeight*5,
+ "s",1,Xoption);
+ GDrawString(lightingGC,lightingWindow,
+ control->buttonQueue[lightTranslucent].buttonX +
+ control->buttonQueue[lightTranslucent].buttonWidth + 3,
+ control->buttonQueue[lightTranslucent].buttonY +
+ lightFontHeight*6,
+ "i",1,Xoption);
+ GDrawString(lightingGC,lightingWindow,
+ control->buttonQueue[lightTranslucent].buttonX +
+ control->buttonQueue[lightTranslucent].buttonWidth + 3,
+ control->buttonQueue[lightTranslucent].buttonY +
+ lightFontHeight*7,
+ "t",1,Xoption);
+ GDrawString(lightingGC,lightingWindow,
+ control->buttonQueue[lightTranslucent].buttonX +
+ control->buttonQueue[lightTranslucent].buttonWidth + 3,
+ control->buttonQueue[lightTranslucent].buttonY +
+ lightFontHeight*8,
+ "y",1,Xoption);
+ drawLightingAxes();
+ drawLightTransArrow();
+
+} /* drawLightingPanel */
+
+
+
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/main3d.c.pamphlet b/src/graph/view3D/main3d.c.pamphlet
new file mode 100644
index 00000000..d8e2ba9b
--- /dev/null
+++ b/src/graph/view3D/main3d.c.pamphlet
@@ -0,0 +1,670 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D main3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _MAIN3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include "header.h"
+#include "cpanel.h"
+#include "process.h"
+#include "bsdsignal.h"
+
+#include "bsdsignal.H1"
+#include "util.H1"
+#include "Gfun.H1"
+#include "XSpadFill.H1"
+#include "XShade.H1"
+#include "all_3d.H1"
+
+ /**********************/
+ /** global variables **/
+ /**********************/
+
+unsigned long * spadColors;
+Display *dsply;
+int scrn;
+XFontStruct *globalFont, *buttonFont, *headerFont, *titleFont, *graphFont,
+ *lightingFont, *volumeFont, *quitFont, *saveFont,*serverFont;
+char scaleReport[5];
+char deltaXReport[5], deltaYReport[5];
+int followMouse=no,
+ viewportKeyNum=0;
+Window rtWindow;
+GC globalGC1, globalGC2, anotherGC, globGC, trashGC,
+ controlMessageGC, lightingGC, volumeGC, quitGC,
+ saveGC, graphGC, componentGC, opaqueGC, renderGC;
+XSizeHints viewSizeHints;
+HashTable *table;
+Colormap colorMap;
+int Socket=1, ack=1;
+
+GC processGC;
+viewPoints *viewport;
+controlPanelStruct *control;
+XGCValues gcVals;
+char *s;
+int someInt;
+
+/* check /usr/include/X11 for current implementation of
+ pixels (e.g. BlackPixel()) */
+unsigned long foregroundColor, backgroundColor;
+
+ /** totalShades is initially set to totalShadesConst.
+ If X cannot allocate 8 shades for each hue, total-
+ Shades is decremented. there is currently only a check for
+ this value to be positive. --> something to add: change over
+ to monochrome if totalShades=0. just modify the spadcolors.c
+ file. spadcolors.c has been modified so that it returns the
+ value for totalShades. since the return value had previously
+ been unused, a modification in this way ensures continued
+ support of other routines calling this function (e.g.
+ hypertex stuff). **/
+
+int mono, totalColors, totalSolid, totalDithered, totalHues,
+ totalSolidShades, totalDitheredAndSolids,totalShades;
+
+int drawMore;
+
+int spadMode=no, /* yes if receiving AXIOM command and
+ calling drawViewport */
+ spadDraw=no; /* yes if drawing viewport for
+ an AXIOM command */
+int spadSignalReceived=0; /* yes if current state is a result of
+ a signal from AXIOM */
+int inNextEvent=no; /* true just before a call to
+ XNextEvent */
+jmp_buf jumpFlag;
+
+char errorStr[80];
+
+view3DStruct viewData;
+
+Window quitWindow, saveWindow;
+
+ /** variables below assume only one viewport per process **/
+
+Window lightingWindow, lightingAxes;
+float lightPointer[3], tempLightPointer[3];
+
+int axesXY[3][4];
+float axesZ[3][2];
+
+float lightIntensity=1.0, tempLightIntensity;
+float backLightIntensity = 1.0;
+
+ /** used for writing viewport info out to a file **/
+char filename[256];
+
+
+ /** used for draw viewport routines */
+float sinTheta, sinPhi, cosTheta, cosPhi, viewScale,
+ viewScaleX, viewScaleY, viewScaleZ, reScale;
+int xCenter, yCenter;
+
+XWindowAttributes vwInfo;
+XWindowAttributes graphWindowAttrib;
+
+XPoint *quadMesh;
+XImage *imageX;
+int *xPts; /* pointer to projected points (x followed by y) */
+float transform[4][4], transform1[4][4],
+ R[4][4], R1[4][4], S[4][4], T[4][4], I[4][4];
+float A[4][4], B[4][4], D[4], E[4][4], F[4], array[4][4];
+
+
+int scanline, polyCount;
+polyList *scanList[ARRAY_HEIGHT];
+float xleft = (float)0 ,xright = (float)ARRAY_WIDTH;
+
+colorBuffer cBuffer[ARRAY_WIDTH];
+float zBuffer[ARRAY_WIDTH];
+
+float zC, dzdx, lum, point_norm[3];
+float intersectColor[2], dcolor;
+triple dpt, dnorm;
+
+ /** eyePoint **/
+float eyePoint[3];
+
+ /** tube stuff **/
+XPoint polygonMesh[20];
+
+ /* bypass the hidden surface algorithm if no rotations, etc */
+int saveFlag=no;
+int firstTime=yes, noTrans = yes, startup = yes;
+int redrawView = no; /* set to yes when returning from
+ subpanels */
+int redoColor = no, pixelSetFlag = no, redoDither = no;
+int redoSmooth = no, multiColorFlag = no;
+
+/* In order to set recalc to true (see draw.h) */
+int finishedList=no, zoomed=yes, translated = yes,
+ changedIntensity, movingLight = no, writeImage = no,
+ rotated=yes, switchedPerspective, changedEyeDistance,
+ gotToggle = no;
+poly *quickList;
+
+ /** if not connected to AXIOM **/
+int viewAloned;
+
+ /** for drawing the box **/
+viewTriple corners[8], clipCorners[8];
+boxSideStruct box[6], clipBox[6];
+
+ /** for freeing up points created frrom split polygons **/
+viewTriple *splitPoints;
+int resMax=0; /* number of points in the split point resevoir */
+
+ /** view volume stuff **/
+Window volumeWindow;
+int frustrumVertex;
+int doingPanel=CONTROLpanel; /* rewrite titles in proper panel */
+int doingVolume;
+
+int screenX; /* global floating point indicating mouse position
+ on frustrum screen */
+float xClipMinN, xClipMaxN, /* normalized values for
+ clip volume */
+ yClipMinN, yClipMaxN,
+ zClipMinN, zClipMaxN,
+ clipValue; /* mouse input */
+float pzMin, pzMax; /* for a given (theta,phi): calculated in
+ drawViewport(), used in drawFrustrum() */
+
+ /** B/W shades **/
+int maxGreyShade=0;
+ /** events from the viewport manager **/
+char propertyName[14];
+char propertyBuffer[256];
+
+ /* global ps variables */
+int psInit=no; /* need to call globaInitPs() each run */
+GCptr GChead=NULL; /* ptr to head of ps GC linked list */
+char *PSfilename; /* output file name used in user directory */
+char *envAXIOM; /* used for ps file paths */
+
+ /** Resource database **/
+XrmDatabase rDB;
+
+ /** variables used for smooth shading **/
+int smoothError = no;
+Pixmap viewmap;
+int viewmap_valid = 0;
+float Cspec = 0.30;
+float Cdiff = 0.4;
+float Camb = 0.3;
+float coeff = 35.0;
+float saturation = 0.8;
+int smoothHue;
+int smoothConst = 50;
+
+
+
+int
+#ifdef _NO_PROTO
+the_handler(display,event)
+ Display *display;
+ XErrorEvent *event;
+#else
+the_handler(Display *display,XErrorEvent *event)
+#endif
+{
+ char buffer[512];
+ XGetErrorText(display,event->error_code,buffer,511);
+ fprintf(stderr,"%s\n",buffer);
+ return(0);
+}
+
+int
+#ifdef _NO_PROTO
+main()
+#else
+main(void)
+#endif
+{
+
+ XGCValues controlGCVals;
+ int i, code;
+
+ char property[256];
+ char *prop = &property[0];
+ char *str_type[20];
+ XrmValue value;
+
+
+ /**** Global inits ****/
+ splitPoints = NIL(viewTriple);
+
+ /**** Set up display ****/
+ if ((dsply = XOpenDisplay(getenv("DISPLAY"))) == NULL)
+ {fprintf(stderr,"Could not open display.\n");exit (-1);}
+ scrn = DefaultScreen(dsply);
+ rtWindow = RootWindow(dsply,scrn);
+ XSetErrorHandler(the_handler);
+ /* XSynchronize(dsply,False); */
+
+ /**** link Xwindows to viewports - X10 feature ****/
+ table = XCreateAssocTable(nbuckets);
+
+ /**** Create AXIOM color map ****/
+ totalShades = 0;
+ totalColors = XInitSpadFill(dsply,scrn,&colorMap,
+ &totalHues,&totalSolidShades,
+ &totalDitheredAndSolids,&totalShades);
+ if (totalColors < 0) {
+ fprintf(stderr,"ERROR: Could not allocate all the necessary colors.\n");
+ exitWithAck(RootWindow(dsply,scrn),Window,-1);
+ }
+
+
+ mergeDatabases();
+
+ /*** Determine whether monochrome or color is used ***/
+ if (XrmGetResource(rDB,"Axiom.3D.monochrome","",str_type,&value) == True){
+ (void) strncpy(prop,value.addr,(int)value.size);
+ }
+ else {
+ (void) strcpy(prop, "off");
+ }
+
+
+ mono = ((totalSolid == 2) || (strcmp(prop,"on") == 0));
+ if (mono) maxGreyShade=XInitShades(dsply,scrn) ;
+
+ if (XrmGetResource(rDB,"Axiom.3D.inverse","",str_type,&value) == True){
+ (void) strncpy(prop,value.addr,(int)value.size);
+ }
+ else {
+ (void) strcpy(prop, "off");
+ }
+
+ if (mono) {
+ if (strcmp(prop,"on") == 0) { /* 0 if equal - inverse video */
+ foregroundColor = white;
+ backgroundColor = black;
+ } else { /* off - no inverse video */
+ foregroundColor = black;
+ backgroundColor = white;
+ }
+ } else { /* inverse of inverse in color (for some strange reason) */
+ if (strcmp(prop,"on") == 0) { /* 0 if equal - inverse video */
+ foregroundColor = white;
+ backgroundColor = black;
+ } else { /* off - no inverse video */
+ foregroundColor = black;
+ backgroundColor = white;
+ }
+ }
+
+ /* read default file name for postScript output */
+ if (XrmGetResource(rDB,"Axiom.3D.postscriptFile","",str_type,&value) == True){
+ (void) strncpy(prop,value.addr,(int)value.size);
+ }
+ else {
+ (void) strcpy(prop, "axiom3D.ps");
+ }
+ PSfilename = (char *)malloc(strlen(prop)+1);
+ strcpy(PSfilename,prop);
+
+ XSync(dsply,0);
+
+ /**** Open global fonts ****/
+ serverFont = XQueryFont(dsply,XGContextFromGC(DefaultGC(dsply,scrn)));
+
+ if (XrmGetResource(rDB,"Axiom.3D.messageFont","Axiom.3D.Font",str_type,&value) == True){
+ (void) strncpy(prop,value.addr,(int)value.size);
+ }
+ else {
+ (void) strcpy(prop,messageFontDefault);
+ }
+ if ((globalFont = XLoadQueryFont(dsply, prop)) == NULL) {
+ fprintf(stderr, "Warning: could not get the %s font for messageFont\n",prop);
+ globalFont = serverFont;
+ }
+
+ if (XrmGetResource(rDB,"Axiom.3D.buttonFont","Axiom.3D.Font",str_type,&value) == True){
+ (void) strncpy(prop,value.addr,(int)value.size);
+ }
+ else {
+ (void) strcpy(prop,buttonFontDefault);
+ }
+ if ((buttonFont = XLoadQueryFont(dsply, prop)) == NULL) {
+ fprintf(stderr, "Warning: could not get the %s font for buttonFont\n",prop);
+ buttonFont = serverFont;
+ }
+
+ if (XrmGetResource(rDB,"Axiom.3D.headerFont","Axiom.3D.Font",str_type,&value) == True){
+ (void) strncpy(prop,value.addr,(int)value.size);
+ }
+ else {
+ (void) strcpy(prop,headerFontDefault);
+ }
+ if ((headerFont = XLoadQueryFont(dsply, prop)) == NULL) {
+ fprintf(stderr, "Warning: could not get the %s font for headerFont\n",prop);
+ headerFont = serverFont;
+ }
+
+ if (XrmGetResource(rDB,"Axiom.3D.titleFont","Axiom.3D.Font",str_type,&value) == True){
+ (void) strncpy(prop,value.addr,(int)value.size);
+ }
+ else {
+ (void) strcpy(prop,titleFontDefault);
+ }
+ if ((titleFont = XLoadQueryFont(dsply, prop)) == NULL) {
+ fprintf(stderr, "Warning: could not get the %s font for titleFont\n",prop);
+ titleFont = serverFont;
+ }
+
+ if (XrmGetResource(rDB,"Axiom.3D.lightingFont","Axiom.3D.Font",str_type,&value) == True){
+ (void) strncpy(prop,value.addr,(int)value.size);
+ }
+ else {
+ (void) strcpy(prop,lightingFontDefault);
+ }
+ if ((lightingFont = XLoadQueryFont(dsply, prop)) == NULL) {
+ fprintf(stderr, "Warning: could not get the %s font for lightingFont\n",prop);
+ lightingFont = serverFont;
+ }
+
+ if (XrmGetResource(rDB,"Axiom.3D.volumeFont","Axiom.3D.Font",str_type,&value) == True){
+ (void) strncpy(prop,value.addr,(int)value.size);
+ }
+ else {
+ (void) strcpy(prop,volumeFontDefault);
+ }
+ if ((volumeFont = XLoadQueryFont(dsply, prop)) == NULL) {
+ fprintf(stderr, "Warning: could not get the %s font for volumeFont\n",prop);
+ volumeFont = serverFont;
+
+ }
+ /**** Create widely used Graphic Contexts ****/
+
+
+ PSGlobalInit();
+ /* must initiate before using any G/PS functions */
+ /* need character name: used as postscript GC variable */
+ /* need to create ps GCs for all GCs used by drawing in viewWindow */
+
+ /* globalGC1 */
+ controlGCVals.foreground = monoColor(axesColor);
+ controlGCVals.background = backgroundColor;
+ globalGC1 = XCreateGC(dsply,rtWindow,GCForeground |
+ GCBackground ,&controlGCVals);
+ carefullySetFont(globalGC1,globalFont);
+ PSCreateContext(globalGC1, "globalGC1", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* controlMessageGC */
+ controlGCVals.foreground = controlMessageColor;
+ controlGCVals.background = backgroundColor;
+ controlMessageGC = XCreateGC(dsply,rtWindow,GCForeground |
+ GCBackground ,&controlGCVals);
+ carefullySetFont(controlMessageGC,globalFont);
+
+ /* globalGC2 */
+ controlGCVals.foreground = monoColor(labelColor);
+ globalGC2 = XCreateGC(dsply,rtWindow,GCForeground,&controlGCVals);
+ carefullySetFont(globalGC2,buttonFont);
+ PSCreateContext(globalGC2, "globalGC2", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* trashGC */
+ controlGCVals.function = GXcopy;
+ trashGC = XCreateGC(dsply,rtWindow,0 ,&controlGCVals);
+ carefullySetFont(trashGC,buttonFont);
+ PSCreateContext(trashGC, "trashGC", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* componentGC */
+ componentGC = XCreateGC(dsply,rtWindow,0 ,&controlGCVals);
+ carefullySetFont(componentGC,buttonFont);
+ PSCreateContext(componentGC, "componentGC", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* opaqueGC */
+ opaqueGC = XCreateGC(dsply,rtWindow,0 ,&controlGCVals);
+ carefullySetFont(opaqueGC,buttonFont);
+ PSCreateContext(opaqueGC, "opaqueGC", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* renderGC */
+ renderGC = XCreateGC(dsply,rtWindow,0,&controlGCVals);
+ carefullySetFont(renderGC,buttonFont);
+ PSCreateContext(renderGC, "renderGC", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* globGC */
+ globGC = XCreateGC(dsply,rtWindow,0,&controlGCVals);
+ carefullySetFont(globGC,headerFont);
+ PSCreateContext(globGC, "globGC", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* anotherGC */
+ controlGCVals.line_width = colorWidth;
+ anotherGC = XCreateGC(dsply,rtWindow,GCBackground | GCLineWidth |
+ GCFunction ,&controlGCVals);
+ carefullySetFont(anotherGC,titleFont);
+ PSCreateContext(anotherGC, "anotherGC", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* also create one for rendering (grayscale only for now) */
+ /* assign arbitrary number to renderGC as 9991 - see header.h */
+ PSCreateContext(GC9991, "renderGC", psNormalWidth, psButtCap,
+ psRoundJoin, psWhite, psBlack );
+
+
+ /* processGC */
+ gcVals.background = backgroundColor;
+ processGC = XCreateGC(dsply,rtWindow,GCBackground |
+ GCFillStyle,&gcVals);
+ carefullySetFont(processGC,buttonFont);
+
+ /* lightingGC */
+ controlGCVals.foreground = monoColor(axesColor);
+ controlGCVals.background = backgroundColor;
+ lightingGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
+ ,&controlGCVals);
+ carefullySetFont(lightingGC,lightingFont);
+
+
+ /* volumeGC */
+ volumeGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
+ ,&controlGCVals);
+ carefullySetFont(volumeGC,volumeFont);
+
+ /* quitGC */
+ quitGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
+ ,&controlGCVals);
+ carefullySetFont(quitGC,buttonFont);
+
+ /* saveGC */
+ saveGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
+ ,&controlGCVals);
+ carefullySetFont(saveGC,buttonFont);
+
+
+ /* graphGC */
+ graphGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
+ ,&controlGCVals);
+ carefullySetFont(graphGC,buttonFont);
+
+ /**** Get Data from the Viewport Manager ****/
+
+ i = 123; /* Used in viewman, what is this for? */
+ code = check(write(Socket,&i,intSize));
+
+ /* Check if I am getting stuff from AXIOM or, if I am viewAlone. */
+ readViewman(&viewAloned,intSize);
+ readViewman(&viewData,sizeof(view3DStruct));
+ readViewman(&i,intSize);
+
+ if (!(viewData.title = (char *)saymem("main.c",i,sizeof(char)))) {
+ fprintf(stderr,"VIEW3D: Fatal Error>> Ran out of memory trying to receive\
+ the title.\n");
+ exitWithAck(RootWindow(dsply,scrn),Window,-1);
+ }
+ readViewman(viewData.title,i);
+
+ readViewman(&(viewData.lightVec[0]),floatSize);
+ readViewman(&(viewData.lightVec[1]),floatSize);
+ readViewman(&(viewData.lightVec[2]),floatSize);
+
+ viewData.scaleDown = yes;
+
+ switch (viewData.typeOf3D) {
+
+ /* Currently, the view3DType information doesn't get sent from
+ AXIOM - all surfaces are alike regardless of how they
+ were created. We may revert back to receiving this information
+ in case we want to take advantage of certain properties of
+ certain surfaces (e.g. z=f(x,y)). */
+
+ case view3DType:
+ case viewTubeType:
+ viewport = make3DComponents();
+ viewData.box = no;
+ viewData.pointSize = 3;
+ break;
+ }; /* switch typeOf3D */
+
+
+ /*************************************************
+ ** Do some temporary assignments that would **
+ ** later be coded in the makeViewport routines **
+ ** when the corresponding code has been put **
+ ** into the viewAlone, viewman and spad files. **
+ *************************************************/
+
+ viewData.distortX = viewData.distortY = viewData.distortZ = 1;
+ viewData.clipPlane = clipPlaneMin;
+ viewData.clipStuff = yes;
+
+ xClipMinN = yClipMinN = zClipMinN = 0.0;
+ xClipMaxN = yClipMaxN = zClipMaxN = 1.0;
+
+ control = viewport->controlPanel;
+
+ bsdSignal(SIGTERM,goodbye,DontRestartSystemCalls);
+ bsdSignal(SIGSEGV,goodbye,DontRestartSystemCalls);
+
+ /** send acknowledgement to viewport manager**/
+ i = 345;
+
+ sprintf(errorStr,"sending window info to viewport manager");
+ check(write(Socket,&(viewport->viewWindow),sizeof(Window)));
+
+ viewmap = XCreatePixmap(dsply,viewport->viewWindow,
+ vwInfo.width,vwInfo.height,
+ DisplayPlanes(dsply,scrn));
+ viewmap_valid = 1;
+
+ processEvents();
+
+ goodbye(-1);
+ return(0); /* control never gets here but compiler complains */
+} /* main() */
+
+
+
+void
+#ifdef _NO_PROTO
+mergeDatabases()
+#else
+mergeDatabases(void)
+#endif
+{
+ XrmDatabase homeDB,serverDB,applicationDB;
+ char filenamebuf[1024];
+ char *filename = &filenamebuf[0];
+ char *classname = "Axiom";
+ char name[255];
+
+ (void) XrmInitialize();
+ (void) strcpy(name, "/usr/lib/X11/app-defaults/");
+ (void) strcat(name, classname);
+ applicationDB = XrmGetFileDatabase(name);
+ (void) XrmMergeDatabases(applicationDB, &rDB);
+
+ if (XResourceManagerString(dsply) != NULL){
+ serverDB = XrmGetStringDatabase(XResourceManagerString(dsply));
+ }
+ else {
+ (void) strcpy(filename,getenv("HOME"));
+ (void) strcat(filename,"/.Xdefaults");
+ serverDB = XrmGetFileDatabase(filename);
+ }
+ XrmMergeDatabases(serverDB,&rDB);
+ if ( getenv ("XENVIRONMENT") == NULL) {
+ int len;
+ (void) strcpy(filename,getenv("HOME"));
+ (void) strcat(filename,"/.Xdefaults-");
+ len = strlen(filename);
+
+ (void) gethostname(filename+len,1024-len);
+
+ }
+ else {
+ (void) strcpy (filename,getenv ("XENVIRONMENT"));
+ }
+ homeDB = XrmGetFileDatabase(filename);
+ XrmMergeDatabases(homeDB,&rDB);
+}
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/mesh3d.c.pamphlet b/src/graph/view3D/mesh3d.c.pamphlet
new file mode 100644
index 00000000..be07bfe7
--- /dev/null
+++ b/src/graph/view3D/mesh3d.c.pamphlet
@@ -0,0 +1,156 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D mesh3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _MESH3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+#include <math.h>
+
+#include "header.h"
+#include "all_3d.H1"
+
+/***************************************************************************
+ *** void getMeshNormal(x0,y0,z0,x1,y1,z1,x2,y2,z2,zMin,zRange,Normal); ***
+ ***************************************************************************/
+
+void
+#ifdef _NO_PROTO
+getMeshNormal(x0,y0,z0,x1,y1,z1,x2,y2,z2,zMin,zRange,Normal)
+ float x0,y0,z0,x1,y1,z1,x2,y2,z2,zMin,zRange,Normal[3];
+#else
+getMeshNormal(float x0,float y0,float z0,float x1,float y1,float z1,
+ float x2,float y2,float z2,float zMin,float zRange,float Normal[3])
+#endif
+{
+ float Ax,Ay,Az,Bx,By,Bz,
+ UnitFactor;
+
+ Ax = x0-x1; Ay = y0-y1; Az = z0-z1;
+ Bx = x2-x1; By = y2-y1; Bz = z2-z1;
+
+ /* compute cross product */
+
+ Normal[0] = (Ay*Bz - Az*By);
+ Normal[1] = (Az*Bx - Ax*Bz);
+ Normal[2] = (Ax*By - Ay*Bx);
+
+ /* normalize normal vector */
+
+ UnitFactor = sqrt(Normal[0]*Normal[0] +
+ Normal[1]*Normal[1] +
+ Normal[2]*Normal[2]);
+ if (UnitFactor > 0.0) {
+ Normal[0] /= UnitFactor;
+ Normal[1] /= UnitFactor;
+ Normal[2] /= UnitFactor;
+ } else {
+ Normal[0] = 0.0;
+ Normal[1] = 0.0;
+ Normal[2] = 0.0;
+ }
+
+} /* getMeshNormal() */
+
+
+/***********************************
+ **** void normalizeVector(v) ****
+ ***********************************/
+
+void
+#ifdef _NO_PROTO
+normalizeVector(v)
+ float *v;
+#else
+normalizeVector(float *v)
+#endif
+{
+ /* v should be a triple (ignoring the rest of the array if necessary) */
+
+ float UnitFactor;
+
+ UnitFactor = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
+ if (UnitFactor != 0.0) {
+ v[0] /= UnitFactor;
+ v[1] /= UnitFactor;
+ v[2] /= UnitFactor;
+ } else {
+ v[0] = v[1] = v[2] = 0.0;
+ }
+
+} /* normalizeVector() */
+
+
+/************************************
+ **** void dotProduct(a,b,size) ****
+ ************************************/
+
+float
+#ifdef _NO_PROTO
+dotProduct(a,b,size)
+ float *a,*b;
+ int size;
+#else
+dotProduct(float * a,float *b,int size)
+#endif
+{
+ int i;
+ float f=0;
+
+ for (i=0; i<size; i++)
+ f += (a[i]*b[i]);
+ return(f);
+
+} /* dotProduct() */
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/msort3d.c.pamphlet b/src/graph/view3D/msort3d.c.pamphlet
new file mode 100644
index 00000000..51f01f02
--- /dev/null
+++ b/src/graph/view3D/msort3d.c.pamphlet
@@ -0,0 +1,199 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D msort3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _MSORT3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+/*****************************************************
+ * Mergesort routine *
+ * *
+ * This file depends on the file msort.h. There, a *
+ * data type called linkElement is defined. It is *
+ * used here and is the main structure being sorted *
+ * here. You can sort any linked structure, under *
+ * any name - so long as it has a next field (see *
+ * below). The define statement, below, renames *
+ * linkElement to linkThing. All you need to do *
+ * is change the define statement to rename *
+ * your structure to linkThing. The first argument *
+ * you pass to the sort routine is a pointer to *
+ * the unsorted list. The function returns with *
+ * that same pointer pointing to a sorted list. *
+ * *
+ * Usage: *
+ * linkElement *msort(p,min,max,compare) *
+ * linkElement *L; *
+ * int min,max; *
+ * int (*compare)(); *
+ * *
+ * e.g. *
+ * msort(L,0,N,compare); *
+ * *
+ * where *
+ * L is the list of things to be sorted, *
+ * it is expected to be a linked list *
+ * where the following element is pointed *
+ * to by a field called "next" *
+ * 0 is the index of the first element *
+ * (since this routine is called recursively, *
+ * this field is kept for clarity; it will *
+ * always be zero at top level) *
+ * N the number of elements in the list *
+ * minus one *
+ * compare(X,Y) is a comparison function that *
+ * returns a -1 if X is less than Y *
+ * 0 if X is the same as Y *
+ * and 1 if X is greater than Y *
+ * *
+ *****************************************************/
+
+
+#include "header.h"
+
+#include "all_3d.H1"
+
+
+#define linkThing poly
+
+
+
+/**********************
+ * merge(p,q,compare) *
+ **********************/
+
+linkThing *
+#ifdef _NO_PROTO
+merge(p,q,compare)
+ linkThing *p,*q;
+ int (*compare)();
+#else
+merge(linkThing *p, linkThing *q,int (*compare)(linkThing *, linkThing *))
+#endif
+{
+ linkThing *returnVal,*current,*pN,*qN;
+
+ /* return if only one item - take out when insert sort implemented */
+ if (!p) return(q); else if (!q) return(p);
+
+ /* set up the head of the list (first element) */
+ if (compare(p,q) <= 0) {
+ returnVal = current = p;
+ pN = p->next;
+ qN = q;
+ } else {
+ returnVal = current = q;
+ pN = p;
+ qN = q->next;
+ }
+
+ /* merge the two lists */
+ while ((pN != NULL) && (qN != NULL)) {
+ if (compare(pN,qN) <= 0) { /* pN <= qN */
+ current->next = pN;
+ current = pN;
+ pN = pN->next;
+ } else {
+ current->next = qN;
+ current = qN;
+ qN = qN->next;
+ }
+ }
+
+ /* tag on the tail end */
+ if (pN == NULL) current->next = qN;
+ else current->next = pN;
+
+ return(returnVal);
+
+} /* merge() */
+
+
+
+/*********************************
+ * msort: the top level function *
+ *********************************/
+
+linkThing *
+#ifdef _NO_PROTO
+msort(p,min,max,compare)
+ linkThing *p;
+ int min,max;
+ int (*compare)();
+#else
+msort(linkThing *p,int min,int max,int (*compare)(linkThing *, linkThing *))
+#endif
+{
+ int mid;
+ int i;
+ linkThing *q,*temp,*xxx;
+
+ if (min == max) return p;
+ else {
+ mid = (min + max - 1)/2;
+ /* e.g. [min,max] = [1,6] => mid=3 => q points to 4th */
+ for (i=min,q=p; i<mid; i++,q=q->next);
+ temp = q->next;
+ q->next = 0;
+ xxx = merge(msort(p,min,mid,compare),
+ msort(temp,mid+1,max,compare), compare);
+
+ return(xxx);
+ }
+
+} /* msort() */
+
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/pot3d.c.pamphlet b/src/graph/view3D/pot3d.c.pamphlet
new file mode 100644
index 00000000..cbf88752
--- /dev/null
+++ b/src/graph/view3D/pot3d.c.pamphlet
@@ -0,0 +1,118 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D pot3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _POT3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include "header.h"
+#include "all_3d.H1"
+
+/****************************/
+/*** void getPotValue() ***/
+/****************************/
+
+mouseCoord
+#ifdef _NO_PROTO
+getPotValue(eX,eY,xH,yH)
+ short eX,eY,xH,yH;
+#else
+getPotValue(short eX,short eY,short xH,short yH)
+#endif
+{
+
+ mouseCoord whereMouse;
+ float x,y;
+
+ x = (float)eX/xH - 1;
+ y = -((float)eY/yH -1);
+
+ /* make non-linear potentiometer */
+ whereMouse.x = x*x*x;
+ whereMouse.y = y*y*y;
+ if (whereMouse.x > 1.0) whereMouse.x = 1.0;
+ if (whereMouse.y > 1.0) whereMouse.y = 1.0;
+ if (whereMouse.x < -1.0) whereMouse.x = -1.0;
+ if (whereMouse.y < -1.0) whereMouse.y = -1.0;
+
+ return(whereMouse);
+
+} /* getPotValue() */
+
+
+
+/**********************************/
+/*** void getLinearPotValue() ***/
+/**********************************/
+
+mouseCoord
+#ifdef _NO_PROTO
+getLinearPotValue(eX,eY,xH,yH)
+ short eX,eY,xH,yH;
+#else
+getLinearPotValue(short eX,short eY,short xH,short yH)
+#endif
+{
+
+ mouseCoord whereMouse;
+
+ whereMouse.x = (float)eX/xH - 1;
+ whereMouse.y = -((float)eY/yH -1);
+
+ return(whereMouse);
+
+} /* getLinearPotValue() */
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/process.h b/src/graph/view3D/process.h
new file mode 100755
index 00000000..82f80c79
--- /dev/null
+++ b/src/graph/view3D/process.h
@@ -0,0 +1,40 @@
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+
+#define maxEyeDistance 2000.0
+#define minEyeDistance 200.0
+#define eyeIncrement 25.0
+
+#define clipPlaneMin (-250.0)
+#define clipPlaneMax 250.0
+#define clipPlaneIncrement 10.0
diff --git a/src/graph/view3D/process3d.c.pamphlet b/src/graph/view3D/process3d.c.pamphlet
new file mode 100644
index 00000000..3fdc608f
--- /dev/null
+++ b/src/graph/view3D/process3d.c.pamphlet
@@ -0,0 +1,1625 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D process3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _PROCESS3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+
+#include "header.h"
+#include "cpanel.h"
+#include "volume.h"
+#include "mode.h"
+#include "process.h"
+#include "draw.h"
+#include "com.h"
+
+
+#include "util.H1"
+#include "Gfun.H1"
+#include "pixmap.H1"
+#include "XShade.H1"
+#include "XSpadFill.H1"
+#include "all_3d.H1"
+
+#define inside(A,B) (((XButtonEvent *)event)->x >= A && \
+ ((XButtonEvent *)event)->x <= B)
+
+
+void
+#ifdef _NO_PROTO
+buttonAction (bKey)
+int bKey;
+#else
+buttonAction (int bKey)
+#endif
+{
+
+ char *s1, *s2;
+ int strL, strL1, strL2, offShade=14;
+
+ /* Button colors which are offColor, RED, are turned off, and those which
+ are onColor, GREEN, indicate the mode is in effect. */
+
+ switch (bKey) {
+
+ case hideControl:
+ if (viewport->haveControl) {
+ viewport->haveControl = no;
+ XUnmapWindow(dsply,control->controlWindow);
+ }
+ break;
+
+ case region3D:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ if (viewport->regionOn) {
+ viewport->regionOn = no;
+ (control->buttonQueue[region3D]).textColor = offColor;
+ viewData.box = 0;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[region3D]).buttonX,
+ (control->buttonQueue[region3D]).buttonY,
+ (control->buttonQueue[region3D]).buttonWidth,
+ (control->buttonQueue[region3D]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[region3D]).buttonX,
+ (control->buttonQueue[region3D]).buttonY,
+ (control->buttonQueue[region3D]).buttonWidth,
+ (control->buttonQueue[region3D]).buttonHeight,Xoption);
+ }
+ } else { /* inverted color for region off */
+ viewport->regionOn = yes;
+ viewData.box = 1;
+ (control->buttonQueue[region3D]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[region3D]).buttonX,
+ (control->buttonQueue[region3D]).buttonY,
+ (control->buttonQueue[region3D]).buttonWidth,
+ (control->buttonQueue[region3D]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[region3D]).buttonX,
+ (control->buttonQueue[region3D]).buttonY,
+ (control->buttonQueue[region3D]).buttonWidth,
+ (control->buttonQueue[region3D]).buttonHeight,Xoption);
+ }
+ }
+
+ s = (control->buttonQueue[region3D]).text;
+ strL = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[region3D]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[region3D]).buttonX +
+ centerX(processGC,s,strL,
+ (control->buttonQueue[region3D]).buttonWidth),
+ (control->buttonQueue[region3D]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[region3D]).buttonHeight),
+ s,strL,Xoption);
+ redoSmooth = yes;
+ drawViewport(Xoption);
+ break;
+
+
+
+ case bwColor:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ if (!mono) {
+ if (viewport->monoOn) {
+ viewport->monoOn = no;
+ if (viewport->hueTop == viewport->hueOffset) redoColor = yes;
+ else redoDither = yes;
+ (control->buttonQueue[bwColor]).textColor = offColor;
+ (control->buttonQueue[bwColor]).text = "BW";
+ } else {
+ viewport->monoOn = yes;
+ maxGreyShade = XInitShades(dsply,scrn);
+ if (viewport->hueTop == viewport->hueOffset) redoColor = yes;
+ else redoDither = yes;
+ (control->buttonQueue[bwColor]).textColor = onColor;
+ (control->buttonQueue[bwColor]).text = "BW";
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[bwColor]).buttonX,
+ (control->buttonQueue[bwColor]).buttonY,
+ (control->buttonQueue[bwColor]).buttonWidth,
+ (control->buttonQueue[bwColor]).buttonHeight);
+ GSetForeground(globalGC1,(float)monoColor(buttonColor),Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[bwColor]).buttonX,
+ (control->buttonQueue[bwColor]).buttonY,
+ (control->buttonQueue[bwColor]).buttonWidth,
+ (control->buttonQueue[bwColor]).buttonHeight,Xoption);
+ }
+
+ s = (control->buttonQueue[bwColor]).text;
+ strL = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[bwColor]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[bwColor]).buttonX +
+ centerX(processGC,s,strL,
+ (control->buttonQueue[bwColor]).buttonWidth),
+ (control->buttonQueue[bwColor]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[bwColor]).buttonHeight),
+ s,strL,Xoption);
+ drawColorMap();
+ redoSmooth = yes;
+ writeTitle();
+ drawViewport(Xoption);
+ }
+ break;
+
+
+
+ case outlineOnOff:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ if (viewData.outlineRenderOn) {
+ viewData.outlineRenderOn = 0;
+ (control->buttonQueue[outlineOnOff]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[outlineOnOff]).buttonX,
+ (control->buttonQueue[outlineOnOff]).buttonY,
+ (control->buttonQueue[outlineOnOff]).buttonWidth,
+ (control->buttonQueue[outlineOnOff]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[outlineOnOff]).buttonX,
+ (control->buttonQueue[outlineOnOff]).buttonY,
+ (control->buttonQueue[outlineOnOff]).buttonWidth,
+ (control->buttonQueue[outlineOnOff]).buttonHeight,Xoption);
+ }
+ } else {
+ viewData.outlineRenderOn = 1;
+ (control->buttonQueue[outlineOnOff]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[outlineOnOff]).buttonX,
+ (control->buttonQueue[outlineOnOff]).buttonY,
+ (control->buttonQueue[outlineOnOff]).buttonWidth,
+ (control->buttonQueue[outlineOnOff]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[outlineOnOff]).buttonX,
+ (control->buttonQueue[outlineOnOff]).buttonY,
+ (control->buttonQueue[outlineOnOff]).buttonWidth,
+ (control->buttonQueue[outlineOnOff]).buttonHeight,Xoption);
+ }
+ }
+ s = (control->buttonQueue[outlineOnOff]).text;
+ strL = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[outlineOnOff]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[outlineOnOff]).buttonX +
+ centerX(processGC,s,strL,
+ (control->buttonQueue[outlineOnOff]).buttonWidth),
+ (control->buttonQueue[outlineOnOff]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[outlineOnOff]).buttonHeight),
+ s,strL,Xoption);
+ if (viewData.style == render) {
+ drawViewport(Xoption);
+ }
+ break;
+
+
+ case lighting:
+ if (saveFlag) {
+ doingPanel = CONTROLpanel;
+ XUnmapWindow(dsply,saveWindow);
+ }
+ doingPanel = LIGHTpanel;
+ tempLightPointer[0] = viewport->lightVector[0];
+ tempLightPointer[1] = viewport->lightVector[1];
+ tempLightPointer[2] = viewport->lightVector[2];
+ tempLightIntensity = lightIntensity;
+ XMapWindow(dsply,lightingWindow);
+ break;
+
+
+ case viewVolume:
+ if (saveFlag) {
+ doingPanel = CONTROLpanel;
+ XUnmapWindow(dsply,saveWindow);
+ }
+ doingPanel = VOLUMEpanel;
+ XMapWindow(dsply,volumeWindow);
+ redrawView = yes;
+ drawViewport(Xoption); /* draw it with doingVolume set to yes */
+ break;
+
+
+ case volumeReturn:
+ doingPanel = CONTROLpanel;
+ redoSmooth = yes;
+ redrawView = yes;
+ XUnmapWindow(dsply,volumeWindow);
+ break;
+
+
+ case volumeAbort:
+ doingPanel = CONTROLpanel;
+ redrawView = yes;
+ XUnmapWindow(dsply,volumeWindow);
+ break;
+
+
+ case lightReturn:
+ doingPanel = CONTROLpanel;
+ viewport->lightVector[0] = lightPointer[0] = tempLightPointer[0];
+ viewport->lightVector[1] = lightPointer[1] = tempLightPointer[1];
+ viewport->lightVector[2] = lightPointer[2] = tempLightPointer[2];
+ lightIntensity = tempLightIntensity;
+ normalizeVector(viewport->lightVector);
+ redrawView = ((viewData.style == render) || (viewData.style == smooth));
+ if (movingLight || changedIntensity) redoSmooth = yes;
+ XUnmapWindow(dsply,lightingWindow);
+ break;
+
+
+ case lightAbort:
+ movingLight = no; changedIntensity = no;
+ doingPanel = CONTROLpanel;
+ XUnmapWindow(dsply,lightingWindow);
+ break;
+
+
+ case resetView:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ viewport->axesOn = yes;
+ viewport->regionOn = no; viewData.box = 0;
+ viewData.outlineRenderOn = 0;
+ viewport->monoOn = no;
+ viewport->zoomXOn = viewport->zoomYOn = viewport->zoomZOn = yes;
+ viewport->originrOn = yes; viewport->objectrOn = no;
+ viewport->originFlag = no;
+ viewport->xyOn = viewport->xzOn = viewport->yzOn = no;
+ viewport->lightVector[0] = -0.5;
+ viewport->lightVector[1] = 0.5;
+ viewport->lightVector[2] = 0.5;
+ viewport->translucency = viewData.translucency;
+ viewport->deltaX = viewport->deltaX0;
+ viewport->deltaY = viewport->deltaY0;
+ viewport->deltaY = viewport->deltaZ0;
+ viewport->scale = viewport->scale0;
+ viewport->scaleX = viewport->scaleY = viewport->scaleZ = 1.0;
+ if (!equal(viewport->theta,viewport->theta0) || !equal(viewport->phi,viewport->phi0))
+ rotated = yes;
+ viewport->theta = viewport->axestheta = viewport->theta0 = viewData.theta;
+ viewport->phi = viewport->axesphi = viewport->phi0 = viewData.phi;
+ viewport->thetaObj = 0.0;
+ viewport->phiObj = 0.0;
+ redoSmooth = yes;
+ drawViewport(Xoption);
+ if (viewport->haveControl) drawControlPanel();
+ writeTitle();
+ break;
+
+
+ case axesOnOff:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ if (viewport->axesOn) {
+ viewport->axesOn = no;
+ (control->buttonQueue[axesOnOff]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[axesOnOff]).buttonX,
+ (control->buttonQueue[axesOnOff]).buttonY,
+ (control->buttonQueue[axesOnOff]).buttonWidth,
+ (control->buttonQueue[axesOnOff]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[axesOnOff]).buttonX,
+ (control->buttonQueue[axesOnOff]).buttonY,
+ (control->buttonQueue[axesOnOff]).buttonWidth,
+ (control->buttonQueue[axesOnOff]).buttonHeight,Xoption);
+ }
+ } else { /* draw invert-color button */
+ viewport->axesOn = yes;
+ (control->buttonQueue[axesOnOff]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[axesOnOff]).buttonX,
+ (control->buttonQueue[axesOnOff]).buttonY,
+ (control->buttonQueue[axesOnOff]).buttonWidth,
+ (control->buttonQueue[axesOnOff]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[axesOnOff]).buttonX,
+ (control->buttonQueue[axesOnOff]).buttonY,
+ (control->buttonQueue[axesOnOff]).buttonWidth,
+ (control->buttonQueue[axesOnOff]).buttonHeight,Xoption);
+ }
+ }
+
+ s = (control->buttonQueue[axesOnOff]).text;
+ strL = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[axesOnOff]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[axesOnOff]).buttonX +
+ centerX(processGC,s,strL,
+ (control->buttonQueue[axesOnOff]).buttonWidth),
+ (control->buttonQueue[axesOnOff]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[axesOnOff]).buttonHeight),
+ s,strL,Xoption);
+ if (viewData.style == smooth) {
+ if (multiColorFlag) redoDither = yes;
+ else redoColor = yes;
+ }
+ drawViewport(Xoption);
+ break;
+
+
+ case zoomx:
+ if (viewport->zoomXOn) {
+ viewport->zoomXOn = no;
+ (control->buttonQueue[zoomx]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[zoomx]).buttonX,
+ (control->buttonQueue[zoomx]).buttonY,
+ (control->buttonQueue[zoomx]).buttonWidth,
+ (control->buttonQueue[zoomx]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[zoomx]).buttonX,
+ (control->buttonQueue[zoomx]).buttonY,
+ (control->buttonQueue[zoomx]).buttonWidth,
+ (control->buttonQueue[zoomx]).buttonHeight,Xoption);
+ }
+ } else {
+ viewport->zoomXOn = yes;
+ (control->buttonQueue[zoomx]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[zoomx]).buttonX,
+ (control->buttonQueue[zoomx]).buttonY,
+ (control->buttonQueue[zoomx]).buttonWidth,
+ (control->buttonQueue[zoomx]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[zoomx]).buttonX,
+ (control->buttonQueue[zoomx]).buttonY,
+ (control->buttonQueue[zoomx]).buttonWidth,
+ (control->buttonQueue[zoomx]).buttonHeight,Xoption);
+ }
+ }
+
+ s = (control->buttonQueue[zoomx]).text;
+ strL = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[zoomx]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[zoomx]).buttonX +
+ centerX(processGC,s,strL,
+ (control->buttonQueue[zoomx]).buttonWidth),
+ (control->buttonQueue[zoomx]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[zoomx]).buttonHeight),
+ s,strL,Xoption);
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ break;
+
+
+ case zoomy:
+ if (viewport->zoomYOn) {
+ viewport->zoomYOn = no;
+ (control->buttonQueue[zoomy]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[zoomy]).buttonX,
+ (control->buttonQueue[zoomy]).buttonY,
+ (control->buttonQueue[zoomy]).buttonWidth,
+ (control->buttonQueue[zoomy]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[zoomy]).buttonX,
+ (control->buttonQueue[zoomy]).buttonY,
+ (control->buttonQueue[zoomy]).buttonWidth,
+ (control->buttonQueue[zoomy]).buttonHeight,Xoption);
+ }
+ } else {
+ viewport->zoomYOn = yes;
+ (control->buttonQueue[zoomy]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[zoomy]).buttonX,
+ (control->buttonQueue[zoomy]).buttonY,
+ (control->buttonQueue[zoomy]).buttonWidth,
+ (control->buttonQueue[zoomy]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[zoomy]).buttonX,
+ (control->buttonQueue[zoomy]).buttonY,
+ (control->buttonQueue[zoomy]).buttonWidth,
+ (control->buttonQueue[zoomy]).buttonHeight,Xoption);
+ }
+ }
+
+ s = (control->buttonQueue[zoomy]).text;
+ strL = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[zoomy]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[zoomy]).buttonX +
+ centerX(processGC,s,strL,
+ (control->buttonQueue[zoomy]).buttonWidth),
+ (control->buttonQueue[zoomy]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[zoomy]).buttonHeight),
+ s,strL,Xoption);
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ break;
+
+
+ case zoomz:
+ if (viewport->zoomZOn) {
+ viewport->zoomZOn = no;
+ (control->buttonQueue[zoomz]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[zoomz]).buttonX,
+ (control->buttonQueue[zoomz]).buttonY,
+ (control->buttonQueue[zoomz]).buttonWidth,
+ (control->buttonQueue[zoomz]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[zoomz]).buttonX,
+ (control->buttonQueue[zoomz]).buttonY,
+ (control->buttonQueue[zoomz]).buttonWidth,
+ (control->buttonQueue[zoomz]).buttonHeight,Xoption);
+ }
+ } else {
+ viewport->zoomZOn = yes;
+ (control->buttonQueue[zoomz]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[zoomz]).buttonX,
+ (control->buttonQueue[zoomz]).buttonY,
+ (control->buttonQueue[zoomz]).buttonWidth,
+ (control->buttonQueue[zoomz]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[zoomz]).buttonX,
+ (control->buttonQueue[zoomz]).buttonY,
+ (control->buttonQueue[zoomz]).buttonWidth,
+ (control->buttonQueue[zoomz]).buttonHeight,Xoption);
+ }
+ }
+
+ s = (control->buttonQueue[zoomz]).text;
+ strL = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[zoomz]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[zoomz]).buttonX +
+ centerX(processGC,s,strL,
+ (control->buttonQueue[zoomz]).buttonWidth),
+ (control->buttonQueue[zoomz]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[zoomz]).buttonHeight),
+ s,strL,Xoption);
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ break;
+
+
+ case originr:
+ viewport->originrOn = yes;
+ (control->buttonQueue[originr]).textColor = onColor;
+ viewport->objectrOn = no;
+ (control->buttonQueue[objectr]).textColor = offColor;
+ viewport->originFlag = yes;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[objectr]).buttonX,
+ (control->buttonQueue[objectr]).buttonY,
+ (control->buttonQueue[objectr]).buttonWidth,
+ (control->buttonQueue[objectr]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[objectr]).buttonX,
+ (control->buttonQueue[objectr]).buttonY,
+ (control->buttonQueue[objectr]).buttonWidth,
+ (control->buttonQueue[objectr]).buttonHeight,Xoption);
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[originr]).buttonX,
+ (control->buttonQueue[originr]).buttonY,
+ (control->buttonQueue[originr]).buttonWidth,
+ (control->buttonQueue[originr]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[originr]).buttonX,
+ (control->buttonQueue[originr]).buttonY,
+ (control->buttonQueue[originr]).buttonWidth,
+ (control->buttonQueue[originr]).buttonHeight,Xoption);
+ }
+ s1 = (control->buttonQueue[objectr]).text;
+ strL1 = strlen(s1);
+ s2 = (control->buttonQueue[originr]).text;
+ strL2 = strlen(s2);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[objectr]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[objectr]).buttonX +
+ centerX(processGC,s1,strL1,
+ (control->buttonQueue[objectr]).buttonWidth),
+ (control->buttonQueue[objectr]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[objectr]).buttonHeight),
+ s1,strL1,Xoption);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[originr]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[originr]).buttonX +
+ centerX(processGC,s2,strL2,
+ (control->buttonQueue[originr]).buttonWidth),
+ (control->buttonQueue[originr]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[originr]).buttonHeight),
+ s2,strL2,Xoption);
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ break;
+
+
+
+ case objectr:
+ viewport->objectrOn = yes;
+ (control->buttonQueue[objectr]).textColor = onColor;
+ viewport->originrOn = no;
+ (control->buttonQueue[originr]).textColor = offColor;
+
+ viewport->originFlag = no;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[originr]).buttonX,
+ (control->buttonQueue[originr]).buttonY,
+ (control->buttonQueue[originr]).buttonWidth,
+ (control->buttonQueue[originr]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[originr]).buttonX,
+ (control->buttonQueue[originr]).buttonY,
+ (control->buttonQueue[originr]).buttonWidth,
+ (control->buttonQueue[originr]).buttonHeight,Xoption);
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[objectr]).buttonX,
+ (control->buttonQueue[objectr]).buttonY,
+ (control->buttonQueue[objectr]).buttonWidth,
+ (control->buttonQueue[objectr]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[objectr]).buttonX,
+ (control->buttonQueue[objectr]).buttonY,
+ (control->buttonQueue[objectr]).buttonWidth,
+ (control->buttonQueue[objectr]).buttonHeight,Xoption);
+ }
+ s1 = (control->buttonQueue[objectr]).text;
+ strL1 = strlen(s1);
+ s2 = (control->buttonQueue[originr]).text;
+ strL2 = strlen(s2);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[objectr]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[objectr]).buttonX +
+ centerX(processGC,s1,strL1,
+ (control->buttonQueue[objectr]).buttonWidth),
+ (control->buttonQueue[objectr]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[objectr]).buttonHeight),
+ s1,strL1,Xoption);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[originr]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[originr]).buttonX +
+ centerX(processGC,s2,strL2,
+ (control->buttonQueue[originr]).buttonWidth),
+ (control->buttonQueue[originr]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[originr]).buttonHeight),
+ s2,strL2,Xoption);
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ break;
+
+
+
+ case ps:
+ strcpy(control->message," Creating postscript file ... ");
+ writeControlMessage();
+ if (PSInit(viewport->viewWindow, viewport->titleWindow) == psError) {
+ strcpy(control->message," Aborted: PSInit error. ");
+ writeControlMessage();
+ return; /* make new tmpnam for new file */
+ }
+
+ redoSmooth = yes;
+ drawViewport(PSoption); /* draw picture in PS; create ps script file */
+
+ if (PSCreateFile(viewBorderWidth, viewport->viewWindow,
+ viewport->titleWindow, viewport->title) == psError) {
+ strcpy(control->message," Aborted: PSCreateFile error. ");
+ writeControlMessage();
+ return;
+ }
+
+ clearControlMessage();
+ strcpy(control->message,PSfilename);
+ strcat(control->message," in working dir ");
+ writeControlMessage();
+ break;
+
+
+
+ case pixmap:
+ strcpy(control->message," Creating axiom3D.xpm now ... ");
+ writeControlMessage();
+ XGetWindowAttributes(dsply,viewport->viewWindow,&vwInfo);
+ write_pixmap_file(dsply,scrn,"axiom3D.xpm",
+ viewport->titleWindow,0,0,vwInfo.width,
+ vwInfo.height+titleHeight);
+ clearControlMessage();
+ strcpy(control->message," axiom3D.xpm in working dir ");
+ writeControlMessage();
+ break;
+
+
+
+ case transparent:
+ case opaqueMesh:
+ case render:
+ case smooth:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ viewData.style = bKey;
+ drawViewport(Xoption); /* draw picture in viewWindow with X routines */
+ break;
+
+
+ case closeAll:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ doingPanel = QUITpanel;
+ viewport->closing = yes;
+ XMapWindow(dsply,quitWindow);
+ break;
+
+
+ case quitReturn:
+ XUnmapWindow(dsply,quitWindow);
+ break;
+
+
+ case quitAbort:
+ doingPanel = CONTROLpanel;
+ XUnmapWindow(dsply,quitWindow);
+ break;
+
+
+ case saveit:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ saveFlag = yes;
+ doingPanel = SAVEpanel;
+ XMapWindow(dsply,saveWindow);
+ break;
+
+
+ case saveExit:
+ saveFlag = no;
+ doingPanel = CONTROLpanel;
+ XUnmapWindow(dsply,saveWindow);
+ break;
+
+
+ case xy:
+ viewport->theta = pi;
+ viewport->phi = 0.0;
+ viewport->axestheta = pi;
+ viewport->axesphi = 0.0;
+ rotated = yes;
+ viewport->yzOn = viewport->xzOn = no;
+ viewport->xyOn = yes;
+ drawViewport(Xoption);
+ break;
+
+
+ case xz:
+ viewport->theta = pi;
+ viewport->phi = -pi_half;
+ viewport->axestheta = pi;
+ viewport->axesphi = -pi_half;
+ rotated = yes;
+ viewport->yzOn = viewport->xyOn = no;
+ viewport->xzOn = yes;
+ drawViewport(Xoption);
+ break;
+
+
+ case yz:
+ viewport->theta = pi_half;
+ viewport->phi = -pi_half;
+ viewport->axestheta = pi_half;
+ viewport->axesphi = -pi_half;
+ rotated = yes;
+ viewport->xzOn = viewport->xyOn = no;
+ viewport->yzOn = yes;
+ drawViewport(Xoption);
+ break;
+
+
+ default:
+ fprintf(stderr,"Received a non-functioning button request: %d \n",bKey);
+ break;
+ } /* switch (action) */
+
+} /* processEvents() */
+
+
+
+/************************** X Event Processing *****************************/
+void
+#ifdef _NO_PROTO
+processEvents()
+#else
+processEvents(void)
+#endif
+{
+
+ XEvent *event, tempEvent;
+ Window whichWindow;
+ buttonStruct *controlButton;
+ mouseCoord mouseXY, linearMouseXY;
+ int someInt, mouseW4, mouseH4;
+ int toggleReady =yes;
+ int checkButton = no;
+ int first_time = yes;
+ int changingColor = yes;
+ int gotEvent = 0, exposeView = no;
+ int tempTW, tempTH, tempVW, tempVH;
+ int buttonTablePtr;
+ float f1, f2;
+ int px, py, lx, ly;
+ unsigned int lbuttons;
+ Window dummy;
+ int Xcon,externalControl,len;
+ fd_set rd;
+
+ externalControl = 0;
+ Xcon = ConnectionNumber(dsply);
+
+ /** assign lightPointer for light panel **/
+ lightPointer[0] = tempLightPointer[0] = viewport->lightVector[0];
+ lightPointer[1] = tempLightPointer[1] = viewport->lightVector[1];
+ lightPointer[2] = tempLightPointer[2] = viewport->lightVector[2];
+
+ if (!(event = (XEvent *)saymem("process.c",1,sizeof(XEvent)))) {
+ fprintf(stderr,"Ran out of memory initializing event processing.\n");
+ exitWithAck(RootWindow(dsply,scrn),Window,-1);
+ }
+
+ controlButton = 0;
+
+ while(1) {
+
+ /* Store old viewport window size attributes for resizing comparison. */
+ XGetWindowAttributes(dsply,viewport->titleWindow,&graphWindowAttrib);
+ tempTW = graphWindowAttrib.width;
+ tempTH = graphWindowAttrib.height;
+ XGetWindowAttributes(dsply,viewport->viewWindow,&graphWindowAttrib);
+ tempVW = graphWindowAttrib.width;
+ tempVH = graphWindowAttrib.height;
+
+ /* Get the next X event. The check for pending events is so that
+ a held down mouse button is interpreted as an event
+ even if nothing is pending. */
+
+ len=0;
+ while(len<=0) {
+ FD_ZERO(&rd);
+ if (externalControl==0) FD_SET(0, &rd);
+ FD_SET(Xcon,&rd);
+
+ if (XEventsQueued(dsply, QueuedAlready)) {
+ len=1;
+ break;
+ }
+ if (!followMouse)
+ len=select(FD_SETSIZE,(void *)&rd,0,0,0);
+ else
+ len=1;
+ }
+
+ if (FD_ISSET(Xcon,&rd)||
+ XEventsQueued(dsply, QueuedAfterFlush) ||
+ followMouse) {
+
+ if (followMouse) {
+ if (XPending(dsply))
+ XNextEvent(dsply,event);
+ gotEvent++;
+ } else {
+ XNextEvent(dsply,event);
+ gotEvent++;
+ }
+
+ if (gotToggle || !followMouse)
+ checkButton = no;
+
+ if (gotEvent) {
+ whichWindow = ((XButtonEvent *)event)->window;
+ first_time = no;
+
+ switch(((XEvent *)event)->type) {
+ case ClientMessage:
+ if (event->xclient.data.l[0] == wm_delete_window) {
+ goodbye(-1);
+ }
+ else {
+ fprintf(stderr,"Unknown Client Message ...\n");
+ }
+ break;
+ case Expose:
+ if (whichWindow == viewport->titleWindow) {
+ exposeView = yes;
+ followMouse = no;
+ XSync(dsply,0);
+ /* get rid of redundant exposure events */
+ XCheckWindowEvent(dsply,viewport->titleWindow,
+ ExposureMask,&tempEvent);
+ writeTitle();
+ XGetWindowAttributes(dsply,viewport->titleWindow,
+ &graphWindowAttrib);
+ if ((graphWindowAttrib.width!=tempTW) ||
+ ((graphWindowAttrib.height)!=tempTH)) {
+ XResizeWindow(dsply,viewport->viewWindow,
+ graphWindowAttrib.width, graphWindowAttrib.height);
+ redoSmooth = yes; /* recompute smooth image pixmap if resized */
+ }
+ } else if (whichWindow == viewport->viewWindow) {
+ exposeView = yes;
+ followMouse = no;
+ XSync(dsply,0);
+ XCheckWindowEvent(dsply,viewport->viewWindow,ExposureMask,
+ &tempEvent);
+ XGetWindowAttributes(dsply,viewport->viewWindow,&graphWindowAttrib);
+ if ((graphWindowAttrib.width!=tempVW) ||
+ ((graphWindowAttrib.height)!=tempVH)) {
+ XResizeWindow(dsply,viewport->viewWindow,graphWindowAttrib.width,
+ graphWindowAttrib.height);
+ redoSmooth = yes; /* recompute smooth image pixmap if resized */
+ }
+ drawViewport(Xoption);
+ XMapWindow(dsply,whichWindow);
+ } else if (whichWindow == lightingWindow) {
+ XGetWindowAttributes(dsply,control->controlWindow,
+ &graphWindowAttrib);
+ /* do not allow resizing of control panel */
+ if ((graphWindowAttrib.width!=controlWidth) ||
+ (graphWindowAttrib.height!=controlHeight)) {
+ XResizeWindow(dsply,control->controlWindow,controlWidth,
+ controlHeight);
+ }
+ drawLightingPanel();
+ } else if (whichWindow == volumeWindow) {
+ XGetWindowAttributes(dsply,control->controlWindow,
+ &graphWindowAttrib);
+ /* do not allow resizing of control panel */
+ if ((graphWindowAttrib.width!=controlWidth) ||
+ (graphWindowAttrib.height!=controlHeight)) {
+ XResizeWindow(dsply,control->controlWindow,controlWidth,
+ controlHeight);
+ }
+ drawVolumePanel();
+ if (redrawView) {
+ redrawView = no;
+ drawViewport(Xoption);
+ }
+ } else if (whichWindow == quitWindow) {
+ XGetWindowAttributes(dsply,control->controlWindow,
+ &graphWindowAttrib);
+ /* do not allow resizing of control panel */
+ if ((graphWindowAttrib.width!=controlWidth) ||
+ (graphWindowAttrib.height!=controlHeight)) {
+ XResizeWindow(dsply,control->controlWindow,controlWidth,
+ controlHeight);
+ }
+ drawQuitPanel();
+ } else if (whichWindow == saveWindow) {
+ XGetWindowAttributes(dsply,control->controlWindow,
+ &graphWindowAttrib);
+ /* do not allow resizing of control panel */
+ if ((graphWindowAttrib.width!=controlWidth) ||
+ (graphWindowAttrib.height!=controlHeight)) {
+ XResizeWindow(dsply,control->controlWindow,controlWidth,
+ controlHeight);
+ }
+ drawSavePanel();
+ } else if (whichWindow == control->controlWindow) {
+ XGetWindowAttributes(dsply,control->controlWindow,
+ &graphWindowAttrib);
+ /* do not allow resizing of control panel */
+ if ((graphWindowAttrib.width != controlWidth) ||
+ (graphWindowAttrib.height != controlHeight)) {
+ XResizeWindow(dsply,control->controlWindow,
+ controlWidth,controlHeight);
+ }
+ if (viewport->haveControl) drawControlPanel();
+ followMouse = no;
+ if (redrawView || exposeView) {
+ redrawView = no;
+ drawViewport(Xoption);
+ }
+ exposeView = no;
+ } else {
+ fprintf(stderr,"Not a valid window.\n");
+ }
+
+ XFlush(dsply);
+ while(XCheckTypedWindowEvent(dsply, whichWindow, Expose, &tempEvent));
+ break;
+
+
+ case MotionNotify:
+ exposeView = no;
+ if (followMouse) {
+ if (whichWindow == control->colormapWindow) {
+ while (XCheckMaskEvent(dsply,ButtonMotionMask,event));
+ first_time = checkButton = followMouse = changingColor = yes;
+ gotToggle = no;
+ } else if (whichWindow != control->controlWindow) {
+ if (controlButton->pot) {
+ while (XCheckMaskEvent(dsply,ButtonMotionMask,event));
+ mouseXY = getPotValue(((XButtonEvent *)event)->x,
+ ((XButtonEvent *)event)->y,
+ controlButton->xHalf,
+ controlButton->yHalf);
+ linearMouseXY = getLinearPotValue(((XButtonEvent *)event)->x,
+ ((XButtonEvent *)event)->y,
+ controlButton->xHalf,
+ controlButton->yHalf);
+ first_time = checkButton = followMouse = yes;
+ gotToggle = no;
+ }
+ }
+ }
+ break;
+
+ case ButtonRelease:
+ exposeView = followMouse = no;
+ toggleReady = yes; gotToggle = yes;
+ break;
+
+ case LeaveNotify:
+ XQueryPointer(dsply,rtWindow,&dummy,&dummy,&px,&py,&lx,&ly,&lbuttons);
+ if ( (controlButton) &&
+ ((whichWindow == control->colormapWindow) ||
+ (controlButton->pot)) &&
+ (lbuttons & Button1Mask ||
+ lbuttons & Button2Mask ||
+ lbuttons & Button3Mask)) {
+ followMouse = yes;
+ if (whichWindow == control->colormapWindow)
+ changingColor = yes;
+ }
+ else {
+ followMouse = no;
+ changingColor = no;
+ }
+ toggleReady = yes;
+ checkButton = exposeView = no;
+ break;
+
+ case ButtonPress:
+ exposeView = no; changingColor = no;
+ if (whichWindow == viewport->viewWindow) {
+ /* find out where the mouse button is pressed on the viewport,
+ this determines where to put the control panel */
+ XGetWindowAttributes(dsply,whichWindow,&graphWindowAttrib);
+ mouseW4 = graphWindowAttrib.width/4;
+ if (((XButtonEvent *)event)->x > (graphWindowAttrib.width-mouseW4))
+ someInt = 1;
+ else {
+ mouseH4 = graphWindowAttrib.height/4;
+ if (((XButtonEvent *)event)->y >
+ (graphWindowAttrib.height - mouseH4)) someInt = 2;
+ else if (((XButtonEvent *)event)->x < mouseW4) someInt = 3;
+ else if (((XButtonEvent *)event)->y < mouseH4) someInt = 4;
+ else someInt = 0;
+ }
+ if (viewport->haveControl) {
+ XUnmapWindow(dsply,control->controlWindow);
+ }
+ putControlPanelSomewhere(someInt);
+ writeControlMessage();
+ XSync(dsply,0);
+ } else if (whichWindow == control->colormapWindow) {
+ gotToggle = no;
+ first_time = checkButton = followMouse = changingColor = yes;
+ } else if (whichWindow != control->controlWindow) {
+ /* mouse clicked on one of the buttons */
+ if (!controlButton || (controlButton->self != whichWindow)) {
+ buttonTablePtr = *((int *)XLookUpAssoc(dsply,table,whichWindow));
+ /** lighting buttons have indices greater than 100 **/
+ /** all buttons share the same array now **/
+ controlButton = &(control->buttonQueue[buttonTablePtr]);
+ }
+ if (controlButton->pot) {
+ /* figure out [x,y] for this button in the range [-1..1,-1..1] */
+ mouseXY = getPotValue(((XButtonEvent *)event)->x,
+ ((XButtonEvent *)event)->y,
+ controlButton->xHalf,controlButton->yHalf);
+ linearMouseXY = getLinearPotValue(((XButtonEvent *)event)->x,
+ ((XButtonEvent *)event)->y,
+ controlButton->xHalf,
+ controlButton->yHalf);
+ followMouse = yes;
+ gotToggle = no;
+ } else {
+ followMouse = no;
+ gotToggle = yes; /* auto-repeat of toggle buttons not allowed */
+ if (toggleReady) toggleReady = no;
+ }
+ checkButton = yes;
+ first_time = yes;
+ }
+ break;
+
+ default:
+ toggleReady = gotToggle = yes;
+ exposeView = changingColor = checkButton = followMouse = no;
+ break;
+
+ } /* switch */
+ gotEvent--;
+ } /* if gotEvent */
+
+ /* Allow a pressed mouse button on a potentiometer to poll repeatedly. */
+ if (followMouse && !first_time && (followMouse++ > mouseWait)) {
+ /* reset for next timing loop */
+ followMouse = yes;
+ checkButton = yes;
+ }
+ if (checkButton) {
+ if (viewport->closing && (controlButton->buttonKey == quitReturn)) {
+ goodbye(-1);
+ } else if (changingColor) {
+ viewport->closing = no;
+ /* moving top color map pointer */
+ if (((XButtonEvent *)event)->y < colorOffsetY) {
+ if (((XButtonEvent *)event)->x < (colorOffset+colorWidth)) {
+ /* decreasing top hue number */
+ if (viewport->hueTop > 0) viewport->hueTop--;
+ } else if (((XButtonEvent *)event)->x >=
+ (colorOffsetX + totalHues*colorWidth + colorWidth)) {
+ if (viewport->hueTop < totalHues) viewport->hueTop++;
+ } else {
+ viewport->hueTop =
+ (((XButtonEvent *)event)->x -
+ colorOffsetX + colorWidth/2 - 13) / colorWidth;
+ }
+ } else if (((XButtonEvent *)event)->y >
+ (colorOffsetY + colorHeight)) {
+ /* moving bottom color map pointer */
+ if (((XButtonEvent *)event)->x < (colorOffset+colorWidth)) {
+ /* decreasing offset number */
+ if (viewport->hueOffset > 0) viewport->hueOffset--;
+ } else if (((XButtonEvent *)event)->x >=
+ (colorOffsetX + totalHues*colorWidth + colorWidth)) {
+ if (viewport->hueOffset < totalHues) viewport->hueOffset++;
+ } else {
+ viewport->hueOffset =
+ (((XButtonEvent *)event)->x -
+ colorOffsetX + colorWidth/2 - 13) / colorWidth;
+ }
+ }
+ /* color map pointer does not wrap around */
+ if (viewport->hueOffset < 0) viewport->hueOffset = 0;
+ if (viewport->hueTop < 0) viewport->hueTop = 0;
+ if (viewport->hueOffset >= totalHues)
+ viewport->hueOffset = totalHues-1;
+ if (viewport->hueTop >= totalHues) viewport->hueTop = totalHues-1;
+ viewport->numberOfHues = viewport->hueTop - viewport->hueOffset;
+ if ((viewport->hueTop == viewport->hueOffset) && !viewport->monoOn) {
+ redoColor = yes;
+ redoDither = no;
+ } else {
+ redoColor = no;
+ redoDither = yes;
+ }
+ /* update color map changes on control panel */
+ drawColorMap();
+ } else {
+ viewport->closing = no;
+ clearControlMessage();
+ /* reset all the things that might affect a recalculation for
+ redrawing removing hidden surfaces */
+
+ /* determine what type of button has been pressed */
+ switch(controlButton->buttonKey) {
+
+ /*** Potentiometers ***/
+ case rotate:
+ if (!((viewport->originrOn) && (viewport->objectrOn))) {
+ /* update the amount of rotation around the object center
+ of volume */
+ if (viewport->objectrOn) {
+ viewport->thetaObj += mouseXY.x * rotateFactor;
+ viewport->phiObj -= mouseXY.y * rotateFactor;
+ while (viewport->thetaObj >= two_pi) {
+ viewport->thetaObj -= two_pi;
+ }
+ while (viewport->thetaObj < 0.0) {
+ viewport->thetaObj += two_pi;
+ }
+ while (viewport->phiObj > pi) {
+ viewport->phiObj -= two_pi;
+ }
+ while (viewport->phiObj <= -pi) {
+ viewport->phiObj += two_pi;
+ }
+ }
+ /* update amount of rotation around the world space origin */
+ if (viewport->originrOn) {
+ viewport->theta += mouseXY.x * rotateFactor;
+ viewport->phi -= mouseXY.y * rotateFactor;
+ while (viewport->theta >= two_pi) {
+ viewport->theta -= two_pi;
+ }
+ while (viewport->theta < 0.0) {
+ viewport->theta += two_pi;
+ }
+ while (viewport->phi > pi) {
+ viewport->phi -= two_pi;
+ }
+ while (viewport->phi <= -pi) {
+ viewport->phi += two_pi;
+ }
+ viewport->axestheta += mouseXY.x * rotateFactor;
+ viewport->axesphi -= mouseXY.y * rotateFactor;
+ while (viewport->axestheta >= two_pi) {
+ viewport->axestheta -= two_pi;
+ }
+ while (viewport->axestheta < 0.0) {
+ viewport->axestheta += two_pi;
+ }
+ while (viewport->axesphi > pi) {
+ viewport->axesphi -= two_pi;
+ }
+ while (viewport->axesphi <= -pi) {
+ viewport->axesphi += two_pi;
+ }
+ }
+ rotated = yes;
+ viewport->yzOn = viewport->xzOn = viewport->xyOn = no;
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ drawViewport(Xoption);
+ }
+ break;
+
+ case zoom:
+ /* if uniform scaling */
+ if ((viewport->zoomXOn) &&
+ (viewport->zoomYOn) &&
+ (viewport->zoomZOn)) {
+ viewport->scale *= 1 - mouseXY.y * scaleFactor;
+ } else { /* else scale axes independently */
+ if (viewport->zoomXOn) viewport->scaleX *= (1 - mouseXY.y);
+ if (viewport->zoomYOn) viewport->scaleY *= (1 - mouseXY.y);
+ if (viewport->zoomZOn) viewport->scaleZ *= (1 - mouseXY.y);
+ }
+ if (viewport->scale > maxScale) viewport->scale = maxScale;
+ else if (viewport->scale < minScale) viewport->scale = minScale;
+ if (viewport->scaleX > maxScale) viewport->scaleX = maxScale;
+ else if (viewport->scaleX < minScale) viewport->scaleX = minScale;
+ if (viewport->scaleY > maxScale) viewport->scaleY = maxScale;
+ else if (viewport->scaleY < minScale) viewport->scaleY = minScale;
+ if (viewport->scaleZ > maxScale) viewport->scaleZ = maxScale;
+ else if (viewport->scaleZ < minScale) viewport->scaleZ = minScale;
+ zoomed = yes;
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ if ((viewport->zoomXOn) ||
+ (viewport->zoomYOn) ||
+ (viewport->zoomZOn))
+ drawViewport(Xoption);
+ break;
+
+ case translate:
+ viewport->deltaX += mouseXY.x * translateFactor;
+ viewport->deltaY += mouseXY.y * translateFactor;
+ if (viewport->deltaX > maxDeltaX) viewport->deltaX = maxDeltaX;
+ else if (viewport->deltaX < -maxDeltaX) viewport->deltaX = -maxDeltaX;
+
+ if (viewport->deltaY > maxDeltaY) viewport->deltaY = maxDeltaY;
+ else if (viewport->deltaY < -maxDeltaY) viewport->deltaY = -maxDeltaY;
+ translated = yes;
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ drawViewport(Xoption);
+ break;
+
+ /*** Lighting panel ***/
+ case lightMoveXY:
+ tempLightPointer[0] = linearMouseXY.x;
+ tempLightPointer[1] = linearMouseXY.y;
+ if (tempLightPointer[0] > 1) tempLightPointer[0] = 1;
+ else if (tempLightPointer[0] < -1) tempLightPointer[0] = -1;
+ if (tempLightPointer[1] > 1) tempLightPointer[1] = 1;
+ else if (tempLightPointer[1] < -1) tempLightPointer[1] = -1;
+ movingLight = yes;
+ drawLightingAxes();
+ break;
+
+ case lightMoveZ:
+ tempLightPointer[2] = linearMouseXY.y;
+ /* linearMouse => no checking necessary */
+ if (tempLightPointer[2] > 1) tempLightPointer[2] = 1;
+ else if (tempLightPointer[2] < -1) tempLightPointer[2] = -1;
+ movingLight = yes;
+ drawLightingAxes();
+ break;
+
+ /* changes the light intensity */
+ case lightTranslucent:
+ tempLightIntensity = (linearMouseXY.y+1)/2;
+ if (tempLightIntensity > 1) tempLightIntensity = 1;
+ else if (tempLightIntensity < 0) tempLightIntensity = 0;
+ changedIntensity = yes;
+ drawLightTransArrow();
+ break;
+
+ /*** volume panel ***/
+ case frustrumBut:
+ screenX = ((XButtonEvent *)event)->x;
+ if inside(eyeMinX,eyeMaxX) {
+ /* object coordinate */
+ f2 = mouseXY.x * (maxEyeDistance - minEyeDistance) +
+ minEyeDistance;
+ if (f2 != viewData.eyeDistance) {
+ doingVolume = 2; /* flag for using screenX */
+ changedEyeDistance = yes;
+ viewData.eyeDistance = f2;
+ drawFrustrum();
+ drawViewport(Xoption);
+ }
+ }
+ else if inside(hitherMinX,hitherMaxX) {
+ f1 = ((float)hitherMaxX - ((XButtonEvent *)event)->x) /
+ (hitherMaxX - hitherMinX);
+ /* object coordinate */
+ f2 = f1 * (clipPlaneMax - clipPlaneMin) + clipPlaneMin;
+ if (f2 != viewData.clipPlane) {
+ doingVolume = 3; /* flag for using screenX */
+ viewData.clipPlane = f2;
+ drawFrustrum();
+ drawViewport(Xoption);
+ }
+ }
+ else {
+ doingVolume = 1; /* check out doingVolume */
+ doingPanel = VOLUMEpanel;
+ }
+ break;
+
+ case clipXBut: /* this is a horizontal button */
+ clipValue = linearMouseXY.x * 0.5 + 0.5; /* normalize to 0..1 */
+ if (lessThan(clipValue,0.0)) clipValue = 0.0;
+ if (greaterThan(clipValue,1.0)) clipValue = 1.0;
+ if (lessThan(linearMouseXY.y,0.0)) {
+ if (!equal(xClipMinN,clipValue)) {
+ if (greaterThan(xClipMaxN-clipValue,minDistXY))
+ xClipMinN = clipValue;
+ else
+ xClipMinN = xClipMaxN - minDistXY;
+ viewData.clipXmin = xClipMinN *
+ (viewData.xmax - viewData.xmin) +
+ viewData.xmin;
+ drawClipXBut();
+ drawClipVolume();
+ if (viewData.clipbox)
+ drawViewport(Xoption);
+ }
+ } else {
+ if (!equal(xClipMaxN,clipValue)) {
+ if (greaterThan(clipValue-xClipMinN,minDistXY))
+ xClipMaxN = clipValue;
+ else
+ xClipMaxN = xClipMinN + minDistXY;
+ viewData.clipXmax = xClipMaxN *
+ (viewData.xmax - viewData.xmin) +
+ viewData.xmin;
+ drawClipXBut();
+ drawClipVolume();
+ if (viewData.clipbox)
+ drawViewport(Xoption);
+ }
+ }
+ break;
+
+ case clipYBut: /* this is a vertical button */
+ /* normalize to 0..1, bottom up */
+ clipValue = 1 - (linearMouseXY.y * 0.5 + 0.5);
+ if (lessThan(clipValue,0.0)) clipValue = 0.0;
+ if (greaterThan(clipValue,1.0)) clipValue = 1.0;
+ if (lessThan(linearMouseXY.x,0.0)) {
+ if (!equal(yClipMinN,clipValue)) {
+ if (greaterThan(yClipMaxN-clipValue,minDistXY))
+ yClipMinN = clipValue;
+ else
+ yClipMinN = yClipMaxN - minDistXY;
+ viewData.clipYmin = yClipMinN *
+ (viewData.ymax - viewData.ymin) +
+ viewData.ymin;
+ drawClipYBut();
+ drawClipVolume();
+ if (viewData.clipbox)
+ drawViewport(Xoption);
+ }
+ } else {
+ if (!equal(yClipMaxN,clipValue)) {
+ if (greaterThan(clipValue-yClipMinN,minDistXY))
+ yClipMaxN = clipValue;
+ else
+ yClipMaxN = yClipMinN + minDistXY;
+ viewData.clipYmax = yClipMaxN *
+ (viewData.ymax - viewData.ymin) +
+ viewData.ymin;
+ drawClipYBut();
+ drawClipVolume();
+ if (viewData.clipbox)
+ drawViewport(Xoption);
+ }
+ }
+ break;
+
+ case clipZBut: /* this is a diagonally aligned button! */
+ /* f1 is the distance from the center of the button along
+ the diagonal line with a slope of -1. If f1 is negative,
+ the direction is downward from the center, if f1 is
+ positive, the direction is upward from the center.
+ Note that there ought to be a constant factor, namely
+ cos(45), multiplied by f1 for the correct normalized value;
+ however, we exploit this by foreshortening the length of the
+ diagonal by that same factor (so instead of normalizing the
+ numbers to, the line we normalize the line to the numbers)
+ since we need to shorten the line at some point anyway
+ (both to match the length of the diagonal side of the box
+ and to allow more area for mouse input. */
+
+ /* cos(45), etc => 0.4 */
+ f1 = (linearMouseXY.x - linearMouseXY.y) * 0.4 + 0.5;
+ if (lessThan(f1,0.0)) f1 = 0.0;
+ if (greaterThan(f1,1.0)) f1 = 1.0;
+ /* note that x<y => moving upward */
+ if (lessThan(-linearMouseXY.x,linearMouseXY.y)) {
+ if (!equal(zClipMaxN,f1)) {
+ if (greaterThan(f1-zClipMinN,minDistZ))
+ zClipMaxN = f1;
+ else
+ zClipMaxN = zClipMinN + minDistZ;
+ viewData.clipZmax = zClipMaxN *
+ (viewData.zmax - viewData.zmin) +
+ viewData.zmin;
+ drawClipZBut();
+ drawClipVolume();
+ if (viewData.clipbox)
+ drawViewport(Xoption);
+ }
+ } else {
+ if (!equal(zClipMinN,f1)) {
+ if (greaterThan(zClipMaxN-f1,minDistZ))
+ zClipMinN = f1;
+ else
+ zClipMinN = zClipMaxN - minDistZ;
+ viewData.clipZmin = zClipMinN *
+ (viewData.zmax - viewData.zmin) +
+ viewData.zmin;
+ drawClipZBut();
+ drawClipVolume();
+ if (viewData.clipbox)
+ drawViewport(Xoption);
+ }
+ } /* if lessThan(x,y) */
+ break;
+
+ case perspectiveBut:
+ if ((viewData.perspective = !viewData.perspective)) {
+ switchedPerspective = yes;
+ GSetForeground(volumeGC,
+ (float)monoColor((control->buttonQueue[perspectiveBut]).textColor),Xoption);
+ GDrawString(volumeGC,volumeWindow,
+ controlButton->buttonX +
+ centerX(volumeGC,"x",1,controlButton->buttonWidth),
+ controlButton->buttonY +
+ centerY(volumeGC,controlButton->buttonHeight),
+ "x",1,Xoption);
+ }
+ else
+ XClearArea(dsply,volumeWindow,
+ controlButton->buttonX+1,
+ controlButton->buttonY+1,
+ controlButton->buttonHeight-2,
+ controlButton->buttonWidth-2,
+ False);
+ drawViewport(Xoption);
+ break;
+
+ case clipRegionBut:
+ if ((viewData.clipbox = !viewData.clipbox)) {
+ GSetForeground(volumeGC,
+ (float)monoColor((control->buttonQueue[clipRegionBut]).textColor),Xoption);
+ GDrawString(volumeGC,volumeWindow,
+ controlButton->buttonX +
+ centerX(volumeGC,"x",1,controlButton->buttonWidth),
+ controlButton->buttonY +
+ centerY(volumeGC,controlButton->buttonHeight),
+ "x",1,Xoption);
+ }
+ else
+ XClearArea(dsply,volumeWindow,
+ controlButton->buttonX+1,
+ controlButton->buttonY+1,
+ controlButton->buttonWidth-2,
+ controlButton->buttonHeight-2,
+ False);
+
+ drawViewport(Xoption);
+ break;
+
+ case clipSurfaceBut:
+ if ((viewData.clipStuff = !viewData.clipStuff)) {
+ GSetForeground(volumeGC,
+ (float)monoColor((control->buttonQueue[clipSurfaceBut]).textColor),Xoption);
+ GDrawString(volumeGC,volumeWindow,
+ controlButton->buttonX +
+ centerX(volumeGC,"x",1,controlButton->buttonWidth),
+ controlButton->buttonY +
+ centerY(volumeGC,controlButton->buttonHeight),
+ "x",1,Xoption);
+ }
+ else
+ XClearArea(dsply,volumeWindow,
+ controlButton->buttonX+1,
+ controlButton->buttonY+1,
+ controlButton->buttonWidth-2,
+ controlButton->buttonHeight-2,
+ False);
+ break;
+
+ default:
+ buttonAction(controlButton->buttonKey);
+ } /* switch on buttonKey */
+
+ } /* else - not closing */
+ } /* if checkButton */
+ } /* if FD_ISSET(Xcon,.. */
+ else if FD_ISSET(0,&rd) {
+ externalControl = spadAction();
+ if (spadDraw && (externalControl==0)) drawViewport(Xoption);
+ }
+ } /* for (until closed) */
+} /* processEvents() */
+
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/project3d.c.pamphlet b/src/graph/view3D/project3d.c.pamphlet
new file mode 100644
index 00000000..2ff174b2
--- /dev/null
+++ b/src/graph/view3D/project3d.c.pamphlet
@@ -0,0 +1,446 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D project3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _PROJECT3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+#include <string.h>
+
+#include "header.h"
+#include "draw.h"
+#include "mode.h" /* for #define components */
+
+#include "all_3d.H1"
+
+/*******************************************
+ * void project(aViewTriple,someXpoints,i) *
+ * *
+ * orthogonal projection for a point *
+ * setting the ith Xpoint as well *
+ *******************************************/
+
+void
+#ifdef _NO_PROTO
+project(aViewTriple,someXpoints,i)
+viewTriple *aViewTriple;
+XPoint *someXpoints;
+int i;
+#else
+project(viewTriple * aViewTriple,XPoint *someXpoints,int i)
+#endif
+{
+ float Vtmp[4], V[4], V1[4];
+
+ V[0] = aViewTriple->x; V[1] = aViewTriple->y;
+ V[2] = aViewTriple->z; V[3] = 1.0;
+
+ if (isNaNPoint(V[0], V[1], V[2])) {
+ (someXpoints+i)->x = aViewTriple->px = NotPoint;
+ (someXpoints+i)->y = aViewTriple->py = NotPoint;
+ return;
+ }
+
+ V[0] -= viewport->transX; V[1] -= viewport->transY;
+ V[2] -= viewport->transZ;
+ vectorMatrix4(V,R1,Vtmp);
+
+ matrixMultiply4x4(S,R,transform);
+ vectorMatrix4(Vtmp,transform,V1);
+
+ aViewTriple->wx = V1[0]; aViewTriple->wy = V1[1];
+ aViewTriple->wz = V1[2];
+
+ V1[0] *= reScale; V1[1] *= reScale; V1[2] *= reScale;
+
+ aViewTriple->pz = V1[2];
+ if (viewData.perspective) {
+ V1[0] *= projPersp(aViewTriple->pz);
+ V1[1] *= projPersp(aViewTriple->pz);
+ }
+
+ matrixMultiply4x4(I,T,transform);
+ vectorMatrix4(V1,transform,V);
+ V[0] = V[0]*viewScale + xCenter;
+ V[1] = vwInfo.height - (V[1]*viewScale + yCenter);
+
+ (someXpoints+i)->x = aViewTriple->px = V[0];
+ (someXpoints+i)->y = aViewTriple->py = V[1];
+}
+
+
+/***************************************************
+ * void projectAPoint(aViewTriple) *
+ * *
+ * orthogonal projection for a point. sort of *
+ * like the above, but no Xpoint assignment *
+ ***************************************************/
+
+void
+#ifdef _NO_PROTO
+projectAPoint(aViewTriple)
+ viewTriple *aViewTriple;
+#else
+projectAPoint(viewTriple *aViewTriple)
+#endif
+{
+ float Vtmp[4], V[4], V1[4];
+
+ V[0] = aViewTriple->x; V[1] = aViewTriple->y;
+ V[2] = aViewTriple->z; V[3] = 1.0;
+
+ if (isNaNPoint(V[0], V[1], V[2])) {
+ aViewTriple->px = NotPoint;
+ aViewTriple->py = NotPoint;
+ return;
+ }
+
+ V[0] -= viewport->transX; V[1] -= viewport->transY;
+ V[2] -= viewport->transZ;
+ vectorMatrix4(V,R1,Vtmp);
+
+ matrixMultiply4x4(S,R,transform);
+ vectorMatrix4(Vtmp,transform,V1);
+
+ aViewTriple->wx = V1[0]; aViewTriple->wy = V1[1];
+ aViewTriple->wz = V1[2];
+
+ V1[0] *= reScale; V1[1] *= reScale; V1[2] *= reScale;
+
+ aViewTriple->pz = V1[2];
+ if (viewData.perspective) {
+ V1[0] *= projPersp(aViewTriple->pz);
+ V1[1] *= projPersp(aViewTriple->pz);
+ }
+
+ matrixMultiply4x4(I,T,transform);
+ vectorMatrix4(V1,transform,V);
+ V[0] = V[0]*viewScale + xCenter;
+ V[1] = vwInfo.height - (V[1]*viewScale + yCenter);
+
+ aViewTriple->px = V[0];
+ aViewTriple->py = V[1];
+}
+
+
+/***************************
+ * void projectAllPoints() *
+ ***************************/
+
+void
+#ifdef _NO_PROTO
+projectAllPoints()
+#else
+projectAllPoints(void)
+#endif
+{
+
+ int i,j,k;
+ LLPoint *anLLPoint;
+ LPoint *anLPoint;
+ int *anIndex;
+
+ anLLPoint = viewData.lllp.llp;
+ for (i=0; i<viewData.lllp.numOfComponents; i++,anLLPoint++) {
+ anLPoint = anLLPoint->lp;
+ for (j=0; j<anLLPoint->numOfLists; j++,anLPoint++) {
+ anIndex = anLPoint->indices;
+ for (k=0; k<anLPoint->numOfPoints; k++,anIndex++) {
+ projectAPoint(refPt3D(viewData,*anIndex));
+ } /* for points in LPoints (k) */
+ } /* for LPoints in LLPoints (j) */
+ } /* for LLPoints in LLLPoints (i) */
+
+} /* projectAllPoints() */
+
+
+/*******************************
+ * void projectAllPolys(pList) *
+ * *
+ * orthogonal projection of *
+ * all the polygons in a given *
+ * list in one go. pz holds *
+ * the projected depth info *
+ * for hidden surface removal. *
+ * Polygons totally outside of *
+ * the window dimensions after *
+ * projection are discarded *
+ * from the list. *
+ *******************************/
+
+void
+#ifdef _NO_PROTO
+projectAllPolys (pList)
+ poly *pList;
+#else
+projectAllPolys (poly *pList)
+#endif
+{
+
+ int i,clipped,clippedPz;
+ float x0=0.0;
+ float y0=0.0;
+ float xA=0.0;
+ float yA=0.0;
+ float xB=0.0;
+ float yB=0.0;
+ int *anIndex;
+ viewTriple *aPt;
+
+ strcpy(control->message," Projecting Polygons ");
+ writeControlMessage();
+
+ projectAllPoints();
+ for (;pList != NIL(poly);pList=pList->next) {
+ /* totalClip==yes => partialClip==yes (of course) */
+ pList->totalClipPz = yes; /* start with 1, AND all points with Pz<0 */
+ pList->partialClipPz = no; /* start with 0, OR any points with Pz<0 */
+ pList->totalClip = yes; /* same idea, only wrt clip volume */
+ pList->partialClip = no;
+ for (i=0,anIndex=pList->indexPtr; i<pList->numpts; i++,anIndex++) {
+ aPt = refPt3D(viewData,*anIndex);
+ clipped = outsideClippedBoundary(aPt->x, aPt->y, aPt->z);
+ pList->totalClip = pList->totalClip && clipped;
+ pList->partialClip = pList->partialClip || clipped;
+ clippedPz = behindClipPlane(aPt->pz);
+ pList->totalClipPz = pList->totalClipPz && clippedPz;
+ pList->partialClipPz = pList->partialClipPz || clippedPz;
+
+ /* stuff for figuring out normalFacingOut, after the loop */
+ if (!i) {
+ x0 = aPt->px; y0 = aPt->py;
+ } else if (i==1) {
+ xA = x0 - aPt->px; yA = y0 - aPt->py;
+ x0 = aPt->px; y0 = aPt->py;
+ } else if (i==2) {
+ xB = aPt->px - x0; yB = aPt->py - y0;
+ }
+ } /* for i */
+ /* store face facing info */
+ /* For now, we shall give faces facing the user a factor of -1,
+ and faces facing away from the user a factor of +1. this is
+ to mimic the eye vector (pointing away from the user) dotted
+ into the surface normal.
+ This routine is being done because the surface normal in object
+ space does not transform over to image space linearly and so
+ has to be recalculated. but the triple product is zero in the
+ X and Y directions so we just take the Z component, of which,
+ we just examine the sign. */
+ if ((x0 = xA*yB - yA*xB) > machine0) pList->normalFacingOut = 1;
+ else if (x0 < machine0) pList->normalFacingOut = -1;
+ else pList->normalFacingOut = 0;
+
+ }
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+
+} /* projectAllPolys */
+
+
+
+/*******************************
+ * void projectAPoly(p) *
+ * *
+ * orthogonal projection of *
+ * all a polygon. pz holds *
+ * the projected depth info *
+ * for hidden surface removal *
+ *******************************/
+
+
+void
+#ifdef _NO_PROTO
+projectAPoly (p)
+ poly *p;
+#else
+projectAPoly (poly *p)
+#endif
+{
+
+ int i,clipped,clippedPz;
+ float Vtmp[4],V[4],V1[4];
+ float x0=0.0;
+ float y0=0.0;
+ float xA=0.0;
+ float yA=0.0;
+ float xB=0.0;
+ float yB=0.0;
+
+ int *anIndex;
+ viewTriple *aPt;
+
+/* totalClip==yes => partialClip==yes */
+ p->totalClipPz = yes; /* start with 1, AND all points with Pz<0 */
+ p->partialClipPz = no; /* start with 0, OR any points with Pz<0 */
+ p->totalClip = yes; /* same idea, only with respect to clip volume */
+ p->partialClip = no;
+ for (i=0,anIndex=p->indexPtr; i<p->numpts; i++,anIndex++) {
+ aPt = refPt3D(viewData,*anIndex);
+ V[0] = aPt->x; V[1] = aPt->y; V[2] = aPt->z; V[3] = 1.0;
+
+ V[0] -= viewport->transX; V[1] -= viewport->transY;
+ V[2] -= viewport->transZ;
+ vectorMatrix4(V,R1,Vtmp);
+
+ matrixMultiply4x4(S,R,transform);
+ vectorMatrix4(Vtmp,transform,V1);
+
+ aPt->wx = V1[0]; aPt->wy = V1[1]; aPt->wz = V1[2];
+
+ V1[0] *= reScale; V1[1] *= reScale; V1[2] *= reScale;
+
+ aPt->pz = V1[2];
+ if (viewData.perspective) {
+ V1[0] *= projPersp(V1[2]);
+ V1[1] *= projPersp(V1[2]);
+ }
+
+ matrixMultiply4x4(I,T,transform);
+ vectorMatrix4(V1,transform,V);
+ V[0] = V[0]*viewScale + xCenter;
+ V[1] = vwInfo.height - (V[1]*viewScale + yCenter);
+
+ aPt->px = V[0]; aPt->py = V[1];
+
+ clipped = outsideClippedBoundary(aPt->x, aPt->y, aPt->z);
+ p->totalClip = p->totalClip && clipped;
+ p->partialClip = p->partialClip || clipped;
+ clippedPz = behindClipPlane(aPt->pz);
+ p->totalClipPz = p->totalClipPz && clippedPz;
+ p->partialClipPz = p->partialClipPz || clippedPz;
+
+ /* stuff for figuring out normalFacingOut, after the loop */
+ if (!i) {
+ x0 = aPt->px; y0 = aPt->py;
+ } else if (i==1) {
+ xA = x0 - aPt->px; yA = y0 - aPt->py;
+ x0 = aPt->px; y0 = aPt->py;
+ } else if (i==2) {
+ xB = aPt->px - x0; yB = aPt->py - y0;
+ }
+ }
+
+ if ((x0 = xA*yB - yA*xB) > machine0) p->normalFacingOut = 1;
+ else if (x0 < machine0) p->normalFacingOut = -1;
+ else p->normalFacingOut = 0;
+
+} /* projectAPoly */
+
+
+
+/**********************************
+ * void projectStuff(x,y,z,px,py) *
+ * *
+ * sort of like the project stuff *
+ * in tube.c but used exclusively *
+ * for the functions of two *
+ * variables. probably will need *
+ * to be changed later to be more *
+ * general (i.e. have everybody *
+ * use the viewTriple point *
+ * structure). *
+ **********************************/
+
+void
+#ifdef _NO_PROTO
+projectStuff(x,y,z,px,py,Pz)
+ float x,y,z;
+ int *px,*py;
+ float *Pz;
+#else
+projectStuff(float x,float y,float z,int *px,int *py,float *Pz)
+#endif
+{
+ float tempx,tempy,tempz,temps,V[4],V1[4],stuffScale=100.0;
+
+ tempx = viewport->scaleX;
+ tempy = viewport->scaleY;
+ tempz = viewport->scaleZ;
+ temps = viewScale;
+
+ if (viewport->scaleX > 5.0) viewport->scaleX = 5.0;
+ if (viewport->scaleY > 5.0) viewport->scaleY = 5.0;
+ if (viewport->scaleZ > 3.0) viewport->scaleZ = 3.0;
+ if (viewScale > 5.0) viewScale = 5.0;
+
+ V[0] = x; V[1] = y;
+ V[2] = z; V[3] = 1.0;
+
+ V[0] -= viewport->transX*stuffScale;
+ V[1] -= viewport->transY*stuffScale;
+ V[2] -= viewport->transZ*stuffScale;
+
+ matrixMultiply4x4(S,R,transform);
+ vectorMatrix4(V,transform,V1);
+ *Pz = V1[2];
+
+ if (viewData.perspective) {
+ V1[0] *= projPersp(V1[2]);
+ V1[1] *= projPersp(V1[2]);
+ }
+
+ matrixMultiply4x4(I,T,transform);
+ vectorMatrix4(V1,transform,V);
+
+ V[0] = V[0]*viewScale + xCenter;
+ V[1] = vwInfo.height - (V[1]*viewScale + yCenter);
+
+ *px = V[0];
+ *py = V[1];
+
+ viewport->scaleX = tempx;
+ viewport->scaleY = tempy;
+ viewport->scaleZ = tempz;
+ viewScale = temps;
+}
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/quit3d.c.pamphlet b/src/graph/view3D/quit3d.c.pamphlet
new file mode 100644
index 00000000..ffc1c726
--- /dev/null
+++ b/src/graph/view3D/quit3d.c.pamphlet
@@ -0,0 +1,193 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D quit3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _QUIT3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include <string.h>
+#include "header.h"
+#include "cpanel.h"
+#include "volume.h"
+#include "../include/purty/volume.bitmap"
+#include "../include/purty/volume.mask"
+
+#include "util.H1"
+#include "Gfun.H1"
+#include "XSpadFill.H1"
+#include "all_3d.H1"
+
+#define quitMASK ExposureMask
+#define quitCursorForeground monoColor(55)
+#define quitCursorBackground monoColor(197)
+#define quitTitleColor monoColor(69)
+#define quitButtonColor monoColor(195)
+#define quitFontHeight (quitFont->max_bounds.ascent+quitFont->max_bounds.descent)
+
+
+/***************************
+ * int makeQuitPanel() *
+ ***************************/
+
+int
+#ifdef _NO_PROTO
+makeQuitPanel()
+#else
+makeQuitPanel(void)
+#endif
+{
+
+ int i;
+ XSetWindowAttributes quitter,QuitterAttrib;
+ XSizeHints sizeh;
+ Pixmap quitbits, quitmask;
+ XColor quitterColor,qColor;
+
+ quitbits = XCreateBitmapFromData(dsply,rtWindow, volumeBitmap_bits,
+ volumeBitmap_width,volumeBitmap_height);
+ quitmask = XCreateBitmapFromData(dsply,rtWindow,volumeMask_bits,
+ volumeMask_width,volumeMask_height);
+ quitter.background_pixel = backgroundColor;
+ quitter.border_pixel = foregroundColor;
+ quitter.event_mask = quitMASK;
+ quitter.colormap = colorMap;
+ quitter.override_redirect = overrideManager;
+ quitterColor.pixel = quitCursorForeground;
+ XQueryColor(dsply,colorMap,&quitterColor);
+ qColor.pixel = quitCursorBackground;
+ XQueryColor(dsply,colorMap,&qColor);
+ quitter.cursor = XCreatePixmapCursor(dsply,quitbits,quitmask,
+ &quitterColor,&qColor,
+ volumeBitmap_x_hot,volumeBitmap_y_hot);
+ quitWindow = XCreateWindow(dsply,control->controlWindow,
+ controlWidth-quitWidth-2,controlHeight-quitHeight-2,
+ quitWidth-2,quitHeight-2,2,
+ CopyFromParent,InputOutput,CopyFromParent,
+ controlCreateMASK,&quitter);
+
+ sizeh.flags = USPosition | USSize;
+ sizeh.x = 0;
+ sizeh.y = 0;
+ sizeh.width = quitWidth-2;
+ sizeh.height = quitHeight-2;
+
+ XSetNormalHints(dsply,quitWindow,&sizeh);
+ XSetStandardProperties(dsply,quitWindow,"Quit Panel","Quit Panel",
+ None,NULL,0,&sizeh);
+
+ /*** do quit buttons ***/
+ initQuitButtons(control->buttonQueue);
+ for (i=quitButtonsStart; i<(quitButtonsEnd); i++) {
+ QuitterAttrib.event_mask = (control->buttonQueue[i]).mask;
+ (control->buttonQueue[i]).self =
+ XCreateWindow(dsply,quitWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,
+ 0,0,InputOnly,CopyFromParent,
+ buttonCreateMASK,&QuitterAttrib);
+ XMakeAssoc(dsply,table,(control->buttonQueue[i]).self,
+ &((control->buttonQueue[i]).buttonKey));
+ XMapWindow(dsply,(control->buttonQueue[i]).self);
+ }
+
+ return(0);
+
+} /* makeQuitPanel() */
+
+
+/****************************
+ * void drawQuitPanel() *
+ ****************************/
+
+void
+#ifdef _NO_PROTO
+drawQuitPanel()
+#else
+drawQuitPanel(void)
+#endif
+{
+
+ char *s;
+ int i,strlength;
+
+ s = "Really?";
+ strlength = strlen(s);
+ GSetForeground(anotherGC,(float)quitTitleColor,Xoption);
+ GDrawString(anotherGC,quitWindow,
+ centerX(anotherGC,s,strlength,quitWidth),centerY(anotherGC,39),s,strlength,Xoption);
+
+ GSetForeground(anotherGC,(float)quitButtonColor,Xoption);
+ for (i=quitButtonsStart; i<(quitButtonsEnd); i++) {
+ GDraw3DButtonOut(quitGC,quitWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,Xoption);
+ s = (control->buttonQueue[i]).text;
+ strlength = strlen(s);
+ GSetForeground(trashGC,
+ (float)monoColor((control->buttonQueue[i]).textColor),Xoption);
+ GDrawString(trashGC,quitWindow,
+ (control->buttonQueue[i]).buttonX +
+ centerX(processGC,s,strlength,
+ (control->buttonQueue[i]).buttonWidth),
+ (control->buttonQueue[i]).buttonY +
+ centerY(processGC,(control->buttonQueue[i]).buttonHeight),
+ s,strlen(s),Xoption);
+ } /* for i in control->buttonQueue */
+
+} /* drawQuitPanel */
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/quitbut3d.c.pamphlet b/src/graph/view3D/quitbut3d.c.pamphlet
new file mode 100644
index 00000000..49957982
--- /dev/null
+++ b/src/graph/view3D/quitbut3d.c.pamphlet
@@ -0,0 +1,109 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D quitbut3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _QUITBUT3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include "header.h"
+#include "cpanel.h"
+
+#include "all_3d.H1"
+
+
+
+int
+#ifdef _NO_PROTO
+initQuitButtons (quitButtons)
+buttonStruct *quitButtons;
+#else
+initQuitButtons (buttonStruct *quitButtons)
+#endif
+{
+ int ii;
+ int num = 0;
+
+ ii = quitAbort;
+ quitButtons[ii].buttonX = 5;
+ quitButtons[ii].buttonY = 41;
+ quitButtons[ii].buttonWidth = 53;
+ quitButtons[ii].buttonHeight = 25;
+ quitButtons[ii].buttonKey = ii;
+ quitButtons[ii].pot = no;
+ quitButtons[ii].mask = buttonMASK;
+ quitButtons[ii].text = "No";
+ quitButtons[ii].textColor = 6;
+ quitButtons[ii].xHalf = quitButtons[ii].buttonWidth/2;
+ quitButtons[ii].yHalf = quitButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = quitReturn;
+ quitButtons[ii].buttonX = 5;
+ quitButtons[ii].buttonY = 75;
+ quitButtons[ii].buttonWidth = 53;
+ quitButtons[ii].buttonHeight = 25;
+ quitButtons[ii].buttonKey = ii;
+ quitButtons[ii].pot = no;
+ quitButtons[ii].mask = buttonMASK;
+ quitButtons[ii].text = "Yes";
+ quitButtons[ii].textColor = onColor;
+ quitButtons[ii].xHalf = quitButtons[ii].buttonWidth/2;
+ quitButtons[ii].yHalf = quitButtons[ii].buttonHeight/2;
+ ++num;
+
+ return(num);
+}
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/save3d.c.pamphlet b/src/graph/view3D/save3d.c.pamphlet
new file mode 100644
index 00000000..8386b418
--- /dev/null
+++ b/src/graph/view3D/save3d.c.pamphlet
@@ -0,0 +1,188 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D save3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _SAVE3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include <stdio.h>
+#include <string.h>
+#include "header.h"
+#include "cpanel.h"
+#include "volume.h"
+#include "../include/purty/volume.bitmap"
+#include "../include/purty/volume.mask"
+
+#include "Gfun.H1"
+#include "XSpadFill.H1"
+#include "all_3d.H1"
+
+#define saveMASK ExposureMask
+#define saveCursorForeground monoColor(55)
+#define saveCursorBackground monoColor(197)
+#define saveTitleColor monoColor(70)
+#define saveButtonColor monoColor(195)
+#define saveFontHeight (saveFont->max_bounds.ascent+saveFont->max_bounds.descent)
+
+
+/***************************
+ * int makeSavePanel() *
+ ***************************/
+
+int
+#ifdef _NO_PROTO
+makeSavePanel()
+#else
+makeSavePanel(void)
+#endif
+{
+
+ int i;
+ XSetWindowAttributes saver,SaverAttrib;
+ XSizeHints sizeh;
+ Pixmap savebits, savemask;
+ XColor saveColor,sColor;
+
+ savebits = XCreateBitmapFromData(dsply,rtWindow, volumeBitmap_bits,
+ volumeBitmap_width,volumeBitmap_height);
+ savemask = XCreateBitmapFromData(dsply,rtWindow,volumeMask_bits,
+ volumeMask_width,volumeMask_height);
+ saver.background_pixel = backgroundColor;
+ saver.border_pixel = foregroundColor;
+ saver.event_mask = saveMASK;
+ saver.colormap = colorMap;
+ saver.override_redirect = overrideManager;
+ saveColor.pixel = saveCursorForeground;
+ XQueryColor(dsply,colorMap,&saveColor);
+ sColor.pixel = saveCursorBackground;
+ XQueryColor(dsply,colorMap,&sColor);
+ saver.cursor = XCreatePixmapCursor(dsply,savebits,savemask,
+ &saveColor,&sColor,
+ volumeBitmap_x_hot,volumeBitmap_y_hot);
+
+ saveWindow = XCreateWindow(dsply,control->controlWindow,
+ controlWidth-saveWidth-2, controlHeight-saveHeight-2,
+ saveWidth-2,saveHeight-2,2,
+ CopyFromParent,InputOutput,CopyFromParent,
+ controlCreateMASK,&saver);
+
+ sizeh.flags = USPosition | USSize;
+ sizeh.x = 0;
+ sizeh.y = 0;
+ sizeh.width = saveWidth-2;
+ sizeh.height = saveHeight-2;
+
+ XSetNormalHints(dsply,saveWindow,&sizeh);
+ XSetStandardProperties(dsply,saveWindow,"Save Panel","Save Panel",
+ None,NULL,0,&sizeh);
+
+ /*** Create save buttons ***/
+ initSaveButtons(control->buttonQueue);
+ for (i=saveButtonsStart; i<(saveButtonsEnd); i++) {
+ SaverAttrib.event_mask = (control->buttonQueue[i]).mask;
+ (control->buttonQueue[i]).self =
+ XCreateWindow(dsply,saveWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,
+ 0,0,InputOnly,CopyFromParent,
+ buttonCreateMASK,&SaverAttrib);
+ XMakeAssoc(dsply,table,(control->buttonQueue[i]).self,
+ &((control->buttonQueue[i]).buttonKey));
+ XMapWindow(dsply,(control->buttonQueue[i]).self);
+ }
+
+ return(0);
+
+} /* makeSavePanel() */
+
+
+/****************************
+ * void drawSavePanel() *
+ ****************************/
+
+void
+#ifdef _NO_PROTO
+drawSavePanel()
+#else
+drawSavePanel(void)
+#endif
+{
+
+ char *s;
+ int i,strlength;
+
+ GSetForeground(saveGC,(float)saveButtonColor,Xoption);
+ for (i=saveButtonsStart; i<(saveButtonsEnd); i++) {
+ GDraw3DButtonOut(saveGC,saveWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,Xoption);
+ s = (control->buttonQueue[i]).text;
+ strlength = strlen(s);
+ GSetForeground(trashGC,
+ (float)monoColor((control->buttonQueue[i]).textColor),Xoption);
+ GDrawString(trashGC,saveWindow,
+ (control->buttonQueue[i]).buttonX +
+ centerX(processGC,s,strlength,
+ (control->buttonQueue[i]).buttonWidth),
+ (control->buttonQueue[i]).buttonY +
+ centerY(processGC,(control->buttonQueue[i]).buttonHeight),
+ s,strlen(s),Xoption);
+ } /* for i in control->buttonQueue */
+
+} /* drawSavePanel */
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/savebut3d.c.pamphlet b/src/graph/view3D/savebut3d.c.pamphlet
new file mode 100644
index 00000000..82382e5f
--- /dev/null
+++ b/src/graph/view3D/savebut3d.c.pamphlet
@@ -0,0 +1,119 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D savebut3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _SAVEBUT3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include "header.h"
+#include "cpanel.h"
+
+#include "all_3d.H1"
+int
+#ifdef _NO_PROTO
+initSaveButtons (saveButtons)
+ buttonStruct *saveButtons;
+#else
+initSaveButtons (buttonStruct *saveButtons)
+#endif
+{
+ int ii;
+ int num = 0;
+
+ ii = saveExit;
+ saveButtons[ii].buttonX = 5;
+ saveButtons[ii].buttonY = 7;
+ saveButtons[ii].buttonWidth = 53;
+ saveButtons[ii].buttonHeight = 25;
+ saveButtons[ii].buttonKey = ii;
+ saveButtons[ii].pot = no;
+ saveButtons[ii].mask = buttonMASK;
+ saveButtons[ii].text = "Cancel";
+ saveButtons[ii].textColor = 6;
+ saveButtons[ii].xHalf = saveButtons[ii].buttonWidth/2;
+ saveButtons[ii].yHalf = saveButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = pixmap;
+ saveButtons[ii].buttonX = 5;
+ saveButtons[ii].buttonY = 41;
+ saveButtons[ii].buttonWidth = 53;
+ saveButtons[ii].buttonHeight = 25;
+ saveButtons[ii].buttonKey = ii;
+ saveButtons[ii].pot = no;
+ saveButtons[ii].mask = buttonMASK;
+ saveButtons[ii].text = "Pixmap";
+ saveButtons[ii].textColor = 28;
+ saveButtons[ii].xHalf = saveButtons[ii].buttonWidth/2;
+ saveButtons[ii].yHalf = saveButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = ps;
+ saveButtons[ii].buttonX = 5;
+ saveButtons[ii].buttonY = 75;
+ saveButtons[ii].buttonWidth = 53;
+ saveButtons[ii].buttonHeight = 25;
+ saveButtons[ii].buttonKey = ii;
+ saveButtons[ii].pot = no;
+ saveButtons[ii].mask = buttonMASK;
+ saveButtons[ii].text = "PS";
+ saveButtons[ii].textColor = 149;
+ saveButtons[ii].xHalf = saveButtons[ii].buttonWidth/2;
+ saveButtons[ii].yHalf = saveButtons[ii].buttonHeight/2;
+
+ return(num);
+}
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/smoothShade3d.c.pamphlet b/src/graph/view3D/smoothShade3d.c.pamphlet
new file mode 100644
index 00000000..03a99c4f
--- /dev/null
+++ b/src/graph/view3D/smoothShade3d.c.pamphlet
@@ -0,0 +1,1143 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D smoothShade3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _SMOOTHSHADE_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include <string.h>
+#include <math.h>
+#include <stdlib.h>
+
+#include "header.h"
+#include "draw.h"
+#include "volume.h"
+#include "mode.h" /* for #define components */
+
+#include "spadcolors.H1"
+#include "Gfun.H1"
+#include "util.H1"
+#include "XSpadFill.H1"
+#include "all_3d.H1"
+
+#define SAFE_VALUE 892347
+
+
+
+
+
+
+char
+#ifdef _NO_PROTO
+get_cBuffer_axes(ix)
+ int ix;
+#else
+get_cBuffer_axes(int ix)
+#endif
+{
+ if( ix >=0 && ix <ARRAY_WIDTH) return (cBuffer[ix].axes);
+ return ('0');
+}
+
+void
+#ifdef _NO_PROTO
+put_cBuffer_axes(ix,val)
+ int ix;
+ char val;
+#else
+put_cBuffer_axes(int ix,char val)
+#endif
+{
+ if( ix >=0 && ix <ARRAY_WIDTH) cBuffer[ix].axes = val;
+}
+
+int
+#ifdef _NO_PROTO
+get_cBuffer_indx(ix)
+ int ix;
+#else
+get_cBuffer_indx(int ix)
+#endif
+{
+ if( ix >=0 && ix <ARRAY_WIDTH) return (cBuffer[ix].indx);
+ return (-1);
+}
+
+void
+#ifdef _NO_PROTO
+put_cBuffer_indx(ix,val)
+ int ix;
+ int val;
+#else
+put_cBuffer_indx(int ix,int val)
+#endif
+{
+ if( ix >=0 && ix <ARRAY_WIDTH) cBuffer[ix].indx = val;
+}
+
+void
+#ifdef _NO_PROTO
+put_zBuffer(ix,val)
+ int ix;
+ float val;
+#else
+put_zBuffer(int ix,float val)
+#endif
+{
+ if (ix >=0 && ix <ARRAY_WIDTH) zBuffer[ix] = val;
+}
+
+float
+#ifdef _NO_PROTO
+get_zBuffer(ix)
+ int ix;
+#else
+get_zBuffer(int ix)
+#endif
+{
+ return (zBuffer[ix]);
+}
+
+void
+#ifdef _NO_PROTO
+put_imageX(ix,val)
+ int ix;
+ char val;
+#else
+put_imageX(int ix,char val)
+#endif
+{
+ if (ix <=0 && ix <vwInfo.width) imageX->data[ix] = val;
+}
+
+
+
+
+/***************************
+ * void drawPhongSpan() *
+ * *
+ * This routine sets the *
+ * buffer values for each *
+ * span of pixels which *
+ * intersect the current *
+ * scanline. *
+ ***************************/
+void
+#ifdef _NO_PROTO
+drawPhongSpan(pt,N,dFlag)
+ triple pt;
+ float N[3];
+ int dFlag;
+#else
+drawPhongSpan(triple pt,float N[3],int dFlag)
+#endif
+{
+ int xpixel,hue,shade;
+ float colorindx, col;
+ triple hs;
+
+
+ /* negative values of xleft and xright have been pushed to machine0 */
+
+ xpixel = (int)xleft;
+
+
+ while (xpixel <= (int)xright) {
+ /* if z is closer to viewer than value in zBuffer continue */
+ if ( (zC < get_zBuffer(xpixel)) ) {
+ /* get the intensity for current point */
+ col = phong(pt,N);
+ put_cBuffer_axes(xpixel,'0');
+ put_zBuffer(xpixel,zC);
+ /* if mono (bw dsply) do black and white semi-random dithering */
+ if (mono || (dFlag == PSoption) || viewport->monoOn) {
+ if (get_random() < 100.0*exp((double)-1.3*(pi_sq*(col-.2)*(col-.2)))) {
+ put_cBuffer_indx(xpixel,black);
+ } else {
+ put_cBuffer_indx(xpixel,white);
+ }
+ } else {
+ /* glossy shading for one hue else dithered for many hues */
+ if (viewport->hueOffset == viewport->hueTop && !smoothError) {
+ colorindx = (float)(smoothConst+1) * col;
+ if (colorindx > (smoothConst+1)) colorindx = smoothConst+1;
+ put_cBuffer_indx(xpixel,XPixelColor((int)colorindx-1));
+ } else { /* probabalistic multi-hued dithering */
+ hs = norm_dist();
+ hue = (int)(intersectColor[0]+hs.x/20.0);
+ /* cannot dither out of color map range */
+ if (viewport->hueOffset < viewport->hueTop) {
+ if (hue < viewport->hueOffset)
+ hue = viewport->hueOffset;
+ else {
+ if (hue > viewport->hueTop)
+ hue = viewport->hueTop;
+ }
+ } else {
+ if (hue < viewport->hueTop)
+ hue = viewport->hueTop;
+ else {
+ if (hue > viewport->hueOffset)
+ hue = viewport->hueOffset;
+ }
+ }
+ col += hs.y/6.0; /* perturb intensity */
+ if (col > 1.0) put_cBuffer_indx(xpixel,white);
+ else {
+ if (col < 0.0) put_cBuffer_indx(xpixel,black);
+ else {
+ shade = (int)(col * 4.0);
+ put_cBuffer_indx(xpixel,XSolidColor(hue,shade));
+ }
+ }
+ }
+ }
+ } /* zC < zBuffer */
+ zC += dzdx;
+ if (viewport->hueOffset != viewport->hueTop || smoothError ||
+ viewport->monoOn)
+ intersectColor[0] += dcolor;
+ N[0] += dnorm.x; N[1] += dnorm.y; N[2] += dnorm.z;
+ pt.x += dpt.x; pt.y += dpt.y; pt.z += dpt.z;
+ xpixel++;
+ } /* while each pixel */
+
+}
+
+
+/***************************
+ * void scanPhong() *
+ * *
+ * This routine takes all *
+ * polygons that intersect *
+ * with the current scan- *
+ * line and calculates the *
+ * intersecting x and z *
+ * points as well as the *
+ * color at each point. *
+ * Interpolation is done *
+ * according to Phong. *
+ ***************************/
+
+void
+#ifdef _NO_PROTO
+scanPhong(dFlag)
+ int dFlag;
+#else
+scanPhong(int dFlag)
+#endif
+{
+ viewTriple *p1, *p2;
+ polyList *polygon;
+ poly *p;
+ int i,num,xtemp,numttt;
+ int *anIndex, *start, *end;
+ float x1,x2,y1,y2,z2,zright,wx1,wx2,wy1,wy2,wz1,wz2;
+ float intersectionx[2], intersectionz[2];
+ float c1,c2,colortemp,ztemp,dY,diffy,diffx,n1[3],n2[3],NV[3];
+ triple ntemp, intersectPt[2], ptemp, pt, intersectN[2];
+
+ /* polygon list intersecting the current scanline, will be modified to
+ edge list structure */
+ polygon = scanList[scanline];
+ while (polygon != NIL(polyList) && polygon->polyIndx != NIL(poly) ) {
+ /* for each polygon in the list */
+ p = polygon->polyIndx;
+ /* don't include clipped polygons */
+ if ( ! ( p->partialClipPz ||
+ p->totalClipPz ||
+ (viewData.clipStuff && (p->partialClip || p->totalClip ) ) ) ) {
+ num = 0; /* 0 & 1, for the 2 edges of polygon that intersect scanline */
+ numttt =0;
+
+ if ((scanline >= (int)p->pymin) && (scanline <= (int)p->pymax)) {
+ /* which edges of the polygon intersect the scanline */
+ for (i=0, anIndex=p->indexPtr; i<p->numpts; i++) {
+ start = anIndex + i;
+ p1 = refPt3D(viewData,*(start));
+ x1 = p1->px; y1 = p1->py; zC = p1->pz; c1 = p1->sc;
+/* if (x1 < machine0){ x1 = machine0; } */
+ wx1 = p1->wx; wy1 = p1->wy; wz1 = p1->wz;
+ n1[0] = p1->norm[0]; n1[1] = p1->norm[1]; n1[2] = p1->norm[2];
+ end = (i != (p->numpts - 1)) ? anIndex + (i + 1) : anIndex;
+ p2 = refPt3D(viewData,*(end));
+ x2 = p2->px; y2 = p2->py; z2 = p2->pz; c2 = p2->sc;
+/* if (x2 < machine0){ x2 = machine0; } */
+ wx2 = p2->wx; wy2 = p2->wy; wz2 = p2->wz;
+ n2[0] = p2->norm[0]; n2[1] = p2->norm[1]; n2[2] = p2->norm[2];
+ /* find beginning and end for intersecting edge */
+ if ((scanline < y1 && scanline >= y2) ||
+ (scanline >= y1 && scanline < y2)) {
+ dY = (float)scanline - y1;
+ diffy = y2 - y1;
+ if (absolute(diffy) < 0.01) diffy = 1.0;
+ intersectionx[num] = x1 + ((x2-x1)/diffy) * dY;
+ intersectionz[num] = zC + ((z2-zC)/diffy) * dY;
+ if (viewport->hueOffset != viewport->hueTop || smoothError ||
+ viewport->monoOn)
+ intersectColor[num] = c1 + ((c2 - c1)/diffy) * dY;
+ intersectN[num].x = n1[0] + ((n2[0] - n1[0])/diffy)*dY;
+ intersectN[num].y = n1[1] + ((n2[1] - n1[1])/diffy)*dY;
+ intersectN[num].z = n1[2] + ((n2[2] - n1[2])/diffy)*dY;
+ intersectPt[num].x = wx1 + ((wx2 - wx1)/diffy)*dY;
+ intersectPt[num].y = wy1 + ((wy2 - wy1)/diffy)*dY;
+ intersectPt[num].z = wz1 + ((wz2 - wz1)/diffy)*dY;
+ num = 1-num;
+ numttt++;
+ } /* if edge intersects scanline */
+ } /* for each edge */
+ if (numttt>=2) { /* if numttt 0 or 1 something has gone wrong */
+ xleft = intersectionx[0]; xright = intersectionx[1];
+ zC = intersectionz[0]; zright = intersectionz[1];
+ /* edges are drawn from left to right, so switch if necessary */
+ if (xright < xleft) {
+ xtemp = xright; xright = xleft; xleft = xtemp;
+ ztemp = zright; zright = zC; zC = ztemp;
+ if (viewport->hueOffset != viewport->hueTop || smoothError ||
+ viewport->monoOn) {
+ colortemp = intersectColor[1];
+ intersectColor[1] = intersectColor[0];
+ intersectColor[0] = colortemp;
+ }
+ ntemp = intersectN[1]; intersectN[1] = intersectN[0];
+ intersectN[0] = ntemp;
+ ptemp = intersectPt[1];
+ intersectPt[1] = intersectPt[0];
+ intersectPt[0] = ptemp;
+ }
+ diffx = xright - xleft;
+ if (absolute(diffx) > .01) {
+ if (viewport->hueOffset != viewport->hueTop || smoothError ||
+ viewport->monoOn)
+ dcolor = (intersectColor[1] - intersectColor[0]) / diffx;
+ dnorm.x = (intersectN[1].x - intersectN[0].x) / diffx;
+ dnorm.y = (intersectN[1].y - intersectN[0].y) / diffx;
+ dnorm.z = (intersectN[1].z - intersectN[0].z) / diffx;
+ dpt.x = (intersectPt[1].x - intersectPt[0].x) / diffx;
+ dpt.y = (intersectPt[1].y - intersectPt[0].y) / diffx;
+ dpt.z = (intersectPt[1].z - intersectPt[0].z) / diffx;
+ dzdx = (zright - zC) / diffx;
+ } else {
+ if (viewport->hueOffset != viewport->hueTop || smoothError ||
+ viewport->monoOn)
+ dcolor = intersectColor[1];
+ dnorm.x = 0.0; dnorm.y = 0.0; dnorm.z = 0.0;
+ dpt.x = 0.0; dpt.y = 0.0; dpt.z = 0.0;
+ dzdx = 0.0;
+ }
+ NV[0] = intersectN[0].x;
+ NV[1] = intersectN[0].y;
+ NV[2] = intersectN[0].z;
+ pt.x = intersectPt[0].x;
+ pt.y = intersectPt[0].y;
+ pt.z = intersectPt[0].z;
+ drawPhongSpan(pt,NV,dFlag);
+ } /* numttt guard */
+ } /* if scanline intersect */
+ } /* clipped */
+ polygon = polygon->next;
+ } /* while still polygons */
+
+}
+
+/********************************************
+ * boxTObuffer() writes the projection of *
+ * the x,y bounding box to the z-buffer. *
+ ********************************************/
+
+void
+#ifdef _NO_PROTO
+boxTObuffer()
+#else
+boxTObuffer(void)
+#endif
+{
+ int xpix,i,j,k,count,decision;
+ int xA,xB,yA,yB;
+ float x,xend,y,yend,diffy,dX,dY,dXY,intersectionx;
+
+ for (i=0;i<6;i++) {
+ if (box[i].inside) {
+ for (j=0; j<3; j++) {
+ quadMesh[j].x = box[i].pointsPtr[j]->px;
+ quadMesh[j].y = box[i].pointsPtr[j]->py;
+ }
+
+ intersectionx = 0.0;
+ for (k=0; k<2; k++) {
+ xA = quadMesh[k].x; yA = quadMesh[k].y;
+ xB = quadMesh[k+1].x; yB = quadMesh[k+1].y;
+
+/*
+ if (xA > graphWindowAttrib.width+1) xA = graphWindowAttrib.width+1;
+ if (xB > graphWindowAttrib.width+1) xB = graphWindowAttrib.width+1;
+ if (yA > graphWindowAttrib.height) yA = graphWindowAttrib.height;
+ if (yB > graphWindowAttrib.height) yB = graphWindowAttrib.height;
+ if (xA < 0) xA = 0; if (xB < 0) xB = 0;
+ if (yA < 0) yA = 0; if (yB < 0) yB = 0;
+*/
+ x = xA; xend = xB; y = yA; yend = yB;
+ diffy = (float)scanline - y;
+ dX = xend - x; dY = yend - y;
+ if (absolute(dY) > machine0) {
+ dXY = dX/dY;
+ } else {
+ dXY = dX;
+ }
+
+ if (dXY < 0.0) dXY = -dXY;
+
+ if ((scanline == (int)y) && (absolute(dY) <= 1.0)) {
+ if (x <= xend) {
+ for (xpix = (int)x; xpix <= (int)xend; xpix++) {
+ put_cBuffer_axes(xpix,'b');
+ }
+ } else {
+ for (xpix = (int)x; xpix >= (int)xend; xpix--) {
+ put_cBuffer_axes(xpix,'b');
+ }
+ }
+ } else {
+ if (xend < x)
+ decision = (scanline < y && scanline >= yend) ||
+ (scanline > y && scanline <= yend);
+ else
+ decision = (scanline <= y && scanline > yend) ||
+ (scanline >= y && scanline < yend);
+ if (decision) {
+ intersectionx = x + dX/dY * diffy;
+ for (count = (int)intersectionx;
+ count <= (int)intersectionx + (int)dXY; count++) {
+ put_cBuffer_axes(count,'b');
+ }
+ }
+ }
+ }
+
+ }
+ }
+
+}
+
+/********************************************
+ * clipboxTObuffer() writes the projection *
+ * of the x,y,z clipping region box to the *
+ * z-buffer. *
+ ********************************************/
+
+void
+#ifdef _NO_PROTO
+clipboxTObuffer()
+#else
+clipboxTObuffer(void)
+#endif
+{
+ int xpix,i,j,k,count,decision;
+ int xA,xB,yA,yB;
+ float x,xend,y,yend,diffy,dX,dY,dXY,intersectionx;
+
+ for (i=0;i<6;i++) {
+ if (clipBox[i].inside) {
+ for (j=0; j<3; j++) {
+ quadMesh[j].x = clipBox[i].pointsPtr[j]->px;
+ quadMesh[j].y = clipBox[i].pointsPtr[j]->py;
+ }
+
+ intersectionx = 0.0;
+ for (k=0; k<2; k++) {
+ xA = quadMesh[k].x; yA = quadMesh[k].y;
+ xB = quadMesh[k+1].x; yB = quadMesh[k+1].y;
+/*
+
+ if (xA > graphWindowAttrib.width+1) xA = graphWindowAttrib.width+1;
+ if (xB > graphWindowAttrib.width+1) xB = graphWindowAttrib.width+1;
+ if (yA > graphWindowAttrib.height) yA = graphWindowAttrib.height;
+ if (yB > graphWindowAttrib.height) yB = graphWindowAttrib.height;
+ if (xA < 0) xA = 0; if (xB < 0) xB = 0;
+ if (yA < 0) yA = 0; if (yB < 0) yB = 0;
+*/
+ x = xA; xend = xB; y = yA; yend = yB;
+ diffy = (float)scanline - y;
+ dX = xend - x; dY = yend - y;
+ if (absolute(dY) > machine0) {
+ dXY = dX/dY;
+ } else {
+ dXY = dX;
+ }
+ if (dXY < 0.0) dXY = -dXY;
+
+ if ((scanline == (int)y) && (absolute(dY) <= 1.0)) {
+ if (x <= xend) {
+ for (xpix = (int)x; xpix <= (int)xend; xpix++) {
+ put_cBuffer_axes(xpix,'c');
+ }
+ } else {
+ for (xpix = (int)x; xpix >= (int)xend; xpix--) {
+ put_cBuffer_axes(xpix,'c');
+ }
+ }
+ } else {
+ if (xend < x)
+ decision = (scanline < y && scanline >= yend) ||
+ (scanline > y && scanline <= yend);
+ else
+ decision = (scanline <= y && scanline > yend) ||
+ (scanline >= y && scanline < yend);
+ if (decision) {
+ intersectionx = x + dX/dY * diffy;
+ for (count = (int)intersectionx;
+ count <= (int)intersectionx + (int)dXY; count++) {
+ put_cBuffer_axes(count,'c');
+ }
+ }
+ }
+ }
+
+ }
+ }
+
+}
+
+
+
+/********************************************
+ * axesTObuffer() writes the projection of *
+ * the x,y,z axes to the z-buffer. *
+ ********************************************/
+
+void
+#ifdef _NO_PROTO
+axesTObuffer()
+#else
+axesTObuffer(void)
+#endif
+{
+ int xpix,i,count,decision;
+ int xA,xB,yA,yB;
+ float x,xend,y,yend,diffy,dX,dY,dXY,intersectionx;
+ float zA,zB,z,zend;
+ float dZ,dZX,dZY,intersectionz;
+
+ intersectionz = 0.0; intersectionx = 0.0;
+ for (i=0; i<3; i++) {
+ xA = axesXY[i][0]; yA = axesXY[i][1]; zA = axesZ[i][0];
+ xB = axesXY[i][2]; yB = axesXY[i][3]; zB = axesZ[i][1];
+/*
+ if (xA > graphWindowAttrib.width+1) xA = graphWindowAttrib.width+1;
+ if (xB > graphWindowAttrib.width+1) xB = graphWindowAttrib.width+1;
+ if (yA > graphWindowAttrib.height) yA = graphWindowAttrib.height;
+ if (yB > graphWindowAttrib.height) yB = graphWindowAttrib.height;
+ if (xA < 0) xA = 0; if (xB < 0) xB = 0;
+ if (yA < 0) yA = 0; if (yB < 0) yB = 0;
+*/
+ x = xA; xend = xB; y = yA; yend = yB; z = zA; zend = zB;
+ diffy = (float)scanline - y;
+ dX = xend - x; dY = yend - y; dZ = zend - z;
+ dZY = dZ/dY;
+ dXY = dX/dY;
+ if (dXY < 0.0) dXY = -dXY;
+ dZX = dZ/dX;
+
+ if ((scanline == (int)y) && (absolute(dY) <= 1.0)) {
+ if (x <= xend) {
+ for (xpix = (int)x; xpix <= (int)xend; xpix++) {
+ put_cBuffer_axes(xpix,'a');
+ put_zBuffer(xpix,z + dZY * diffy);
+ } /* for x */
+ } else {
+ for (xpix = (int)x; xpix >= (int)xend; xpix--) {
+ put_cBuffer_axes(xpix,'a');
+ put_zBuffer(xpix,z + dZY * diffy);
+ } /* for x */
+ }
+ } else {
+ if (xend < x)
+ decision = (scanline < y && scanline >= yend) ||
+ (scanline > y && scanline <= yend);
+ else
+ decision = (scanline <= y && scanline > yend) ||
+ (scanline >= y && scanline < yend);
+ if (decision) {
+ intersectionx = x + dX/dY * diffy;
+ intersectionz = z + dZY * diffy;
+ for (count = (int)intersectionx;
+ count <= (int)intersectionx + (int)dXY; count++) {
+ put_cBuffer_axes(count,'a');
+ put_zBuffer(count,intersectionz);
+ intersectionz += dZX;
+ }
+ } /* if edge intersects scanline */
+ }
+ } /* for each axes */
+
+}
+
+/********************************************
+ * scanLines() scanline z-buffer algorithm *
+ * initialize z-buffer and color buffer for *
+ * all scanlines. *
+ ********************************************/
+
+void
+#ifdef _NO_PROTO
+scanLines(dFlag)
+ int dFlag;
+#else
+scanLines(int dFlag)
+#endif
+{
+ unsigned long pixColor;
+ int i;
+ char tempA;
+
+ if (dFlag == Xoption) {
+ if (viewmap_valid) {
+ XFreePixmap(dsply,viewmap);
+ viewmap_valid=0;
+ }
+ viewmap = XCreatePixmap(/* display */ dsply,
+ /* drawable */ viewport->viewWindow,
+ /* width */ vwInfo.width,
+ /* height */ vwInfo.height,
+ /* depth */ DefaultDepth(dsply,scrn));
+ viewmap_valid =1;
+ GSetForeground(trashGC,(float)backgroundColor,dFlag);
+ XFillRectangle(dsply,viewmap,trashGC,0,0,vwInfo.width,vwInfo.height);
+ XFillRectangle(dsply,viewport->viewWindow,trashGC,0,0,
+ vwInfo.width,vwInfo.height);
+ } else {
+ GSetForeground(GC9991,
+ 1.0-(float)((int)(psShadeMax-0.3*psShadeMax)-1)*psShadeMul,dFlag);
+ quadMesh[0].x = 0; quadMesh[0].y = 0;
+ quadMesh[1].x = graphWindowAttrib.width+2;
+ quadMesh[1].y = 0;
+ quadMesh[2].x = graphWindowAttrib.width+2;
+ quadMesh[2].y = graphWindowAttrib.height;
+ quadMesh[3].x = 0;
+ quadMesh[3].y = graphWindowAttrib.height;
+ quadMesh[4].x = 0; quadMesh[4].y = 0;
+ PSFillPolygon(GC9991, quadMesh, 5);
+ }
+
+ if (graphWindowAttrib.height >= physicalHeight)
+ graphWindowAttrib.height = physicalHeight - 1;
+ if (graphWindowAttrib.width >= physicalWidth)
+ graphWindowAttrib.width = physicalWidth - 1;
+ if (dFlag == Xoption)
+ strcpy(control->message," Display Scanlines ");
+ else
+ strcpy(control->message," Writing Output ");
+ writeControlMessage();
+
+ scanline = graphWindowAttrib.height-1;
+
+ imageX = XCreateImage(/* display */ dsply,
+ /* visual */ DefaultVisual(dsply,scrn),
+ /* depth */ DefaultDepth(dsply,scrn),
+ /* format */ ZPixmap,
+ /* offset */ 0,
+ /* data */ 0,
+ /* width */ vwInfo.width,
+ /* height */ 1,
+ /* bitmap_pad */ 32,
+ /* bytes_per_line */ 0);
+ imageX->data = (char *)malloc(imageX->bytes_per_line);
+
+
+ while (scanline >= 0 && keepDrawingViewport()) {
+ /* initialize buffer values for scanline */
+ pixColor = backgroundColor;
+ for (i=0; i < (int)graphWindowAttrib.width; i++) {
+ put_zBuffer(i,10000.0);
+ put_cBuffer_indx(i,-1);
+ put_cBuffer_axes(i,'0');
+ if (mono || viewport->monoOn)
+ if ((scanline % 2) == 0)
+ if ((i % 2) == 0) {
+ if (i>=0 && i<vwInfo.width) XPutPixel(imageX,i,0,backgroundColor);
+ }
+ else {
+ if (i>=0 && i<vwInfo.width) XPutPixel(imageX,i,0,foregroundColor);
+ }
+ else
+ if ((i % 2) == 0) {
+ if (i>=0 && i<vwInfo.width) XPutPixel(imageX,i,0,foregroundColor);
+ }
+ else {
+ if (i>=0 && i<vwInfo.width) XPutPixel(imageX,i,0,backgroundColor);
+ }
+ else {
+ if (i>=0 && i<vwInfo.width) XPutPixel(imageX,i,0,backgroundColor);
+ }
+ }
+
+ /* writes the axes info to the buffers */
+ if (viewData.box) boxTObuffer();
+ if (viewData.clipbox) clipboxTObuffer();
+ if (viewport->axesOn) axesTObuffer();
+
+ /* fill buffers for current scanline */
+ scanPhong(dFlag);
+
+ for (i=0; i < (int)graphWindowAttrib.width; i++) {
+ /* include bounding region info */
+ if (viewData.box) {
+ if (get_cBuffer_axes(i) == 'b') {
+ if (dFlag==Xoption) {
+ if (mono || (viewport->monoOn)) pixColor = foregroundColor;
+ else pixColor = boxInline;
+ if (i >=0 && i<vwInfo.width) XPutPixel(imageX,i,0,pixColor);
+ } else {
+ GSetForeground(GC9991, psBlack, dFlag );
+ GDrawPoint(viewport->viewWindow, GC9991, i,scanline,dFlag);
+ }
+ }
+ }
+ /* include clipping box info */
+ if (viewData.clipbox) {
+ if (get_cBuffer_axes(i)== 'c') {
+ if (dFlag==Xoption) {
+ if (mono || (viewport->monoOn)) pixColor = foregroundColor;
+ else pixColor = clipBoxInline;
+ if (i >=0 && i<vwInfo.width) XPutPixel(imageX,i,0,pixColor);
+ } else {
+ GSetForeground(GC9991, psBlack, dFlag );
+ GDrawPoint(viewport->viewWindow, GC9991, i,scanline,dFlag);
+ }
+ }
+ }
+ /* include axes info */
+ if (viewport->axesOn) {
+ if (get_cBuffer_axes(i) == 'a') {
+ if (dFlag == Xoption) {
+ if (mono || (viewport->monoOn)) pixColor = foregroundColor;
+ else pixColor = monoColor(axesColor);
+ if (i >=0 && i<vwInfo.width) XPutPixel(imageX,i,0,pixColor);
+ } else {
+ GSetForeground(GC9991,psBlack,dFlag);
+ GDrawPoint(viewport->viewWindow, GC9991, i,scanline,dFlag);
+ }
+ } /* if buffer slot is an axes point */
+ tempA = get_cBuffer_axes(i);
+ } else tempA = '0'; /* else axes not on */
+
+ if (get_cBuffer_indx(i) >= 0 && (tempA == '0')) {
+ if (dFlag == Xoption) {
+ GSetForeground(trashGC,(float)get_cBuffer_indx(i),dFlag);
+ pixColor = get_cBuffer_indx(i);
+ if (i >=0 && i<vwInfo.width) XPutPixel(imageX,i,0,pixColor);
+ }
+ else {
+ GSetForeground(GC9991,(float)get_cBuffer_indx(i),dFlag);
+ GDrawPoint(viewport->viewWindow, GC9991, i,scanline,dFlag);
+ }
+ }
+ } /* for each pixel in scanline */
+
+ if (dFlag == Xoption) {
+ XPutImage(dsply,viewport->viewWindow,trashGC,imageX,0,0,0,
+ scanline,vwInfo.width,1);
+ XPutImage(dsply,viewmap,trashGC,imageX,0,0,0,
+ scanline,vwInfo.width,1);
+ }
+
+ scanline--;
+
+ } /* while each scanline */
+ XDestroyImage(imageX);
+
+}
+
+/*************************************
+ * void freePolyList(); *
+ * *
+ * frees up the global scanList l-l *
+ *************************************/
+
+void
+#ifdef _NO_PROTO
+freePolyList ()
+#else
+freePolyList (void)
+#endif
+{
+ polyList *P, *nextP;
+ int i;
+
+ for (i = 0; (i < ARRAY_HEIGHT); i++) {
+ P = scanList[i];
+ while((P != NIL(polyList))) {
+ nextP = P->next;
+ free(P);
+ P = nextP;
+ }
+ }
+
+} /* freePolyList() */
+
+
+/********************************************
+ * showAxesLabels() writes the axes labels *
+ * onto the viewmap of a graph. *
+ ********************************************/
+
+void
+#ifdef _NO_PROTO
+showAxesLabels(dFlag)
+ int dFlag;
+#else
+showAxesLabels(int dFlag)
+#endif
+{
+ int xcoord2,ycoord2;
+
+ if (dFlag == Xoption)
+ if (mono || (viewport->monoOn))
+ GSetForeground(globGC,(float)foregroundColor,dFlag);
+ else
+ GSetForeground(globGC,(float)monoColor(labelColor),dFlag);
+ else GSetForeground(GC9991,psBlack,dFlag);
+
+ /* axes label for X */
+ if ((int)axesZ[0][0] >= (int)axesZ[0][2]) {
+ if (axesXY[0][2] < axesXY[0][0]) xcoord2 = axesXY[0][2]-5;
+ else xcoord2 = axesXY[0][2] + 5;
+ if (axesXY[0][3] < axesXY[0][1]) ycoord2 = axesXY[0][3]-5;
+ else ycoord2 = axesXY[0][3] + 5;
+ if (!viewport->yzOn) {
+ if (dFlag == Xoption)
+ GDrawString(globGC,viewmap,xcoord2,ycoord2,"X",1,dFlag);
+ else
+ GDrawString(GC9991,viewport->viewWindow,xcoord2,ycoord2,"X",1,dFlag);
+ }
+ }
+
+ /* axes label for Y */
+ if ((int)axesZ[1][0] >= (int)axesZ[1][1]) {
+ if (axesXY[1][2] < axesXY[1][0]) xcoord2 = axesXY[1][2]-5;
+ else xcoord2 = axesXY[1][2] + 5;
+ if (axesXY[1][3] < axesXY[1][1]) ycoord2 = axesXY[1][3]-5;
+ else ycoord2 = axesXY[1][3] + 5;
+ if (!viewport->xzOn) {
+ if (dFlag == Xoption)
+ GDrawString(globGC,viewmap,xcoord2,ycoord2,"Y",1,dFlag);
+ else
+ GDrawString(GC9991,viewport->viewWindow,xcoord2,ycoord2,"Y",1,dFlag);
+ }
+ }
+
+ /* axes label for Z */
+ if ((int)axesZ[2][0] >= (int)axesZ[2][1]) {
+ if (axesXY[2][2] < axesXY[2][0]) xcoord2 = axesXY[2][2]-5;
+ else xcoord2 = axesXY[2][2] + 5;
+ if (axesXY[2][3] < axesXY[2][1]) ycoord2 = axesXY[2][3]-5;
+ else ycoord2 = axesXY[2][3] + 5;
+ if (!viewport->xyOn) {
+ if (dFlag == Xoption)
+ GDrawString(globGC,viewmap,xcoord2,ycoord2,"Z",1,dFlag);
+ else
+ GDrawString(GC9991,viewport->viewWindow,xcoord2,ycoord2,"Z",1,dFlag);
+ }
+ }
+}
+
+
+
+/********************************************
+ * changeColorMap() modifies the color map *
+ * for moving in and out of smooth shading. *
+ ********************************************/
+
+void
+#ifdef _NO_PROTO
+changeColorMap()
+#else
+changeColorMap(void)
+#endif
+{
+ int okay, i, hue, *index;
+ poly *cp;
+ viewTriple *pt;
+
+ strcpy(control->message," Make New Color Map ");
+ writeControlMessage();
+ if ((viewport->hueOffset == viewport->hueTop) &&
+ !mono && !viewport->monoOn) {
+
+ /* colormap is not an even distribution across spectrum */
+ /* see spadcolors.c code to understand why this is done */
+
+ if (viewport->hueTop < 11) smoothHue = viewport->hueTop * 6;
+ else
+ if (viewport->hueTop > 10 && viewport->hueTop < 16) {
+ smoothHue = viewport->hueTop*20 - 140;
+ }
+ else {
+ smoothHue = viewport->hueTop*12 - 12;
+ }
+
+ if (redoColor) {
+ /* reallocate colormap for new hue */
+ redoColor = no;
+ if (pixelSetFlag) {
+ FreePixels(dsply,colorMap,smoothConst+1);
+ }
+ okay = makeNewColorMap(dsply,colorMap,smoothHue);
+ if (okay) {
+ pixelSetFlag = yes;
+ smoothError = no; }
+ else {
+ pixelSetFlag = no;
+ smoothError = yes; }
+ } /* if redoColor */
+ } else {
+ redoDither = no;
+ if (pixelSetFlag && !mono) {
+ FreePixels(dsply,colorMap,smoothConst);
+ pixelSetFlag = no;
+ redoColor = no;
+ multiColorFlag = yes;
+ }
+ if (!mono && !viewport->monoOn) {
+ cp = quickList;
+ while (cp != NIL(poly) && keepDrawingViewport()) {
+ for (i = 0, index = cp->indexPtr;
+ i < cp->numpts; i++, index++) {
+ pt = refPt3D(viewData,*(index));
+ /* get hue for each point if multi-dithering is used */
+ if (absolute(cp->color) > 1.0)
+ hue = floor(absolute(cp->color));
+ else
+ hue = floor(absolute(cp->color) * viewport->numberOfHues) +
+ viewport->hueOffset;
+ pt->sc = (float)hue;
+ } /* for each point in polygon */
+ cp = cp->next;
+ }
+ } /* multi-color dither */
+ } /* else hueOffset != hueTop */
+}
+
+
+/***********************
+ * void drawPhong() *
+ * *
+ * A general routine *
+ * for displaying a *
+ * list of polygons *
+ * using a simple *
+ * scanline z-buffer *
+ * algorithm with *
+ * phong shading. *
+ ***********************/
+
+void
+#ifdef _NO_PROTO
+drawPhong(dFlag)
+ int dFlag;
+#else
+drawPhong(int dFlag)
+#endif
+{
+
+ poly *p, *head;
+ polyList *s;
+ int i,j,hue;
+ int *anIndex, redo;
+ viewTriple *aPoint, *polyPt;
+
+ redo = (recalc || redoSmooth);
+ if (redo || redoColor || redoDither) {
+ rotated = no; zoomed = no; translated = no;
+ switchedPerspective = no; changedEyeDistance = no;
+ redoSmooth = no; movingLight = no;
+
+ /* If only a color change don't recalculate polygon info. */
+ if (!redo) {
+ /* glossy shading if a single hue is indicated */
+ changeColorMap();
+ scanLines(dFlag);
+ /* if axes are on then show axes labels */
+ if (viewport->axesOn) showAxesLabels(dFlag);
+
+ /* show pixmap of image */
+ XCopyArea(dsply,viewmap,viewport->viewWindow,trashGC,0,0,
+ vwInfo.width,vwInfo.height,0,0);
+ } else {
+ if (keepDrawingViewport()) {
+ if (!firstTime && !(scanline > 0)) {
+ strcpy(control->message," Freeing Polygons ");
+ writeControlMessage();
+ freeListOfPolygons(quickList);
+ freePointResevoir();
+ }
+ if (keepDrawingViewport()) {
+ strcpy(control->message," Collecting Polygons ");
+ writeControlMessage();
+ quickList = copyPolygons(viewData.polygons);
+
+ if (keepDrawingViewport()) {
+ strcpy(control->message," Projecting Polygons ");
+ writeControlMessage();
+ projectAllPolys(quickList);
+ if (keepDrawingViewport()) {
+ strcpy(control->message,
+ " Setting Polygon Extremes ");
+ writeControlMessage();
+ minMaxPolygons(quickList);
+ if (keepDrawingViewport()) {
+ strcpy(control->message,
+ " Sorting Polygons ");
+ writeControlMessage();
+ quickList = msort(quickList,0,viewData.numPolygons,
+ polyCompare);
+ calcEyePoint();
+ head = p = quickList;
+
+ /* glossy shading if a single hue is indicated */
+ changeColorMap();
+
+ for (i=0, aPoint=viewData.points;
+ i<viewData.numOfPoints; i++,aPoint++) {
+ aPoint->norm[0]= 0.0;
+ aPoint->norm[1]= 0.0;
+ aPoint->norm[2]= 0.0;
+ }
+ freePolyList();
+ for (i = 0; i < ARRAY_HEIGHT; i++)
+ scanList[i] = NIL(polyList);
+ /* for each polygon */
+ /* calculate average normal for each vertex */
+ strcpy(control->message,
+ " Build Polygon Lists ");
+ writeControlMessage();
+ p = head;
+ while ((p != NIL(poly)) && keepDrawingViewport()) {
+
+ for (j = 0, anIndex = p->indexPtr;
+ j < p->numpts; j++, anIndex++) {
+ polyPt = refPt3D(viewData,*(anIndex));
+ polyPt->norm[0] += p->N[0];
+ polyPt->norm[1] += p->N[1];
+ polyPt->norm[2] += p->N[2];
+ normalizeVector(polyPt->norm);
+ /* get hue for each point if multi-dithering is used */
+ if ((viewport->hueOffset != viewport->hueTop ||
+ smoothError) && !mono) {
+ if (absolute(p->color) > 1.0) {
+ hue = floor(absolute(p->color));
+ } else {
+ hue = floor(absolute(p->color) *
+ viewport->numberOfHues) +
+ viewport->hueOffset;
+ }
+ polyPt->sc = (float)hue;
+ } /* multi-color dither */
+ } /* for each point in polygon */
+
+ if ( ! ( p->partialClipPz ||
+ p->totalClipPz ||
+ (viewData.clipStuff && (p->partialClip || p->totalClip ) ) ) ) {
+ /* put polygon in each scanline list it intersects */
+ for (i=(int)p->pymin; i<= (int)p->pymax; i++) {
+ if ( (i>=0) && (i<ARRAY_HEIGHT ) ){
+ s = (polyList *)saymem("smoothShade.c",1,sizeof(polyList));
+ s->polyIndx = p;
+ s->next = scanList[i];
+ scanList[i] = s;
+ }
+ } /* put polygon in each scanline it intersects */
+ } /* if polygon not clipped */
+ p = p->next;
+ } /* while still polygons */
+
+ scanLines(dFlag);
+
+ /* if axes are on then show axes labels */
+ if (viewport->axesOn) showAxesLabels(dFlag);
+
+ /* show pixmap of image */
+ XCopyArea(dsply,viewmap,viewport->viewWindow,trashGC,0,0,
+ vwInfo.width,vwInfo.height,0,0);
+ /* freePolyList(scanList); */
+
+ } /* keepDrawingViewport() after setting extreme values */
+ } /* keepDrawingViewport() after projecting all polygons */
+ } /* keepDrawingViewport() after collecting polygons */
+ } /* keepDrawingViewport() after freeing polygons */
+ } /* keepDrawingViewport() after recalc */
+ finishedList = !(scanline>0);
+ if (firstTime) firstTime = no;
+ } /* not only a color change */
+
+ } else { /* else just redisplay current pixmap of image */
+ XCopyArea(dsply,viewmap,viewport->viewWindow,trashGC,0,0,
+ vwInfo.width,vwInfo.height,0,0);
+ }
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+
+} /* drawPhong */
+
+
+
+
+
+
+
+
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/spadAction3d.c.pamphlet b/src/graph/view3D/spadAction3d.c.pamphlet
new file mode 100644
index 00000000..da8d1916
--- /dev/null
+++ b/src/graph/view3D/spadAction3d.c.pamphlet
@@ -0,0 +1,431 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D spadAction3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _SPADACTION3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "header.h"
+#include "process.h"
+#include "draw.h"
+
+#include "util.H1"
+#include "all_3d.H1"
+
+int
+#ifdef _NO_PROTO
+readViewman (info,size)
+ void *info;
+ int size;
+#else
+readViewman (void *info,int size)
+#endif
+{
+ int m = 0;
+
+ sprintf(errorStr,"%s","read from viewport manager\n");
+ m = check(read( 0, info, size));
+
+ return(m);
+
+}
+void
+#ifdef _NO_PROTO
+scalePoint (p)
+ viewTriple *p;
+#else
+scalePoint (viewTriple *p)
+#endif
+{
+
+ p->x *= viewData.scaleToView;
+ p->y *= viewData.scaleToView;
+ p->z *= viewData.scaleToView;
+
+ if (viewData.cmin != viewData.cmax)
+ p->c = (p->c - viewData.cmin)/(viewData.cmax-viewData.cmin);
+ if (p->c > 1.0) p->c = 1.0;
+ else if (p->c < 0) p->c = 0.0;
+
+} /* scalePoint */
+
+
+/********************
+ * int spadAction() *
+ ********************/
+
+int
+#ifdef _NO_PROTO
+spadAction ()
+#else
+spadAction (void)
+#endif
+{
+ int code, viewCommand;
+ float f1, f2, f3;
+ int i1, i2, i3;
+
+
+ if (viewAloned==yes) {
+ close(0);
+ return(-1);
+ }
+ readViewman(&viewCommand, intSize);
+
+ switch (viewCommand) {
+
+ case rotate:
+ readViewman(&f1, floatSize);
+ readViewman(&f2, floatSize);
+ viewport->theta = f1;
+ viewport->phi = f2;
+ while (viewport->theta >= two_pi) viewport->theta -= two_pi;
+ while (viewport->theta < 0.0) viewport->theta += two_pi;
+ while (viewport->phi > pi) viewport->phi -= two_pi;
+ while (viewport->phi <= -pi) viewport->phi += two_pi;
+ viewport->axestheta = viewport->theta;
+ viewport->axesphi = viewport->phi;
+ spadDraw=yes;
+ rotated=yes;
+ viewport->yzOn = viewport->xzOn = viewport->xyOn = no;
+
+ break;
+
+ case zoom:
+ readViewman(&f1, floatSize);
+ viewport->scale = f1;
+ if (viewport->scale > maxScale) viewport->scale = maxScale;
+ else if (viewport->scale < minScale) viewport->scale = minScale;
+
+ spadDraw=yes;
+ zoomed = yes;
+ break;
+
+ case zoomx:
+ readViewman(&f1, floatSize);
+ readViewman(&f2, floatSize);
+ readViewman(&f3, floatSize);
+ viewport->scaleX = f1; viewport->scaleY = f2; viewport->scaleZ = f3;
+ if ((viewport->scaleX == 1.0) &&
+ (viewport->scaleY == 1.0) &&
+ (viewport->scaleZ == 1.0)) {
+ viewport->zoomXOn = viewport->zoomYOn = viewport->zoomZOn = yes;
+ } else {
+ if (viewport->scaleX == 1.0) viewport->zoomXOn = no;
+ else {
+ if (viewport->scaleX > maxScale) viewport->scaleX = maxScale;
+ else if (viewport->scaleX < minScale) viewport->scaleX = minScale;
+ }
+ if (viewport->scaleY == 1.0) viewport->zoomYOn = no;
+ else {
+ if (viewport->scaleY > maxScale) viewport->scaleY = maxScale;
+ else if (viewport->scaleY < minScale) viewport->scaleY = minScale;
+ }
+ if (viewport->scaleZ == 1.0) viewport->zoomZOn = no;
+ else {
+ if (viewport->scaleZ > maxScale) viewport->scaleZ = maxScale;
+ else if (viewport->scaleZ < minScale) viewport->scaleZ = minScale;
+ }
+ }
+
+ spadDraw=yes;
+ zoomed = yes;
+ break;
+
+ case translate:
+ readViewman(&(viewport->deltaX),floatSize);
+ readViewman(&(viewport->deltaY),floatSize);
+ if (viewport->deltaX > maxDeltaX) viewport->deltaX = maxDeltaX;
+ else if (viewport->deltaX < -maxDeltaX) viewport->deltaX = -maxDeltaX;
+ if (viewport->deltaY > maxDeltaY) viewport->deltaY = maxDeltaY;
+ else if (viewport->deltaY < -maxDeltaY) viewport->deltaY = -maxDeltaY;
+ spadDraw=yes;
+ translated = yes;
+ break;
+
+ case modifyPOINT:
+ readViewman(&i1,intSize);
+ i1--;
+ readViewman(&(refPt3D(viewData,i1)->x),floatSize);
+ readViewman(&(refPt3D(viewData,i1)->y),floatSize);
+ readViewman(&(refPt3D(viewData,i1)->z),floatSize);
+ readViewman(&(refPt3D(viewData,i1)->c),floatSize);
+ scalePoint(refPt3D(viewData,i1));
+ spadDraw=yes;
+ break;
+
+ case hideControl:
+ readViewman(&i1,intSize);
+ if (i1) { /* show control panel */
+ if (viewport->haveControl)
+ XUnmapWindow(dsply,control->controlWindow);
+ putControlPanelSomewhere(someInt);
+ } else { /* turn off control panel */
+ if (viewport->haveControl) {
+ viewport->haveControl = no;
+ XUnmapWindow(dsply,control->controlWindow);
+ }
+ }
+ break;
+
+ case axesOnOff:
+ readViewman(&i1,intSize);
+ viewport->axesOn = i1;
+ spadDraw=yes;
+ if (viewData.style == smooth) {
+ if (multiColorFlag) redoDither = yes;
+ else redoColor = yes;
+ }
+ if (viewport->haveControl) drawControlPanel();
+ break;
+
+/* Non-uniform scaling is not in AXIOM yet. */
+/* Neither is object or origin rotation. */
+
+ case perspectiveOnOff:
+ readViewman(&i1,intSize);
+ viewData.perspective = i1;
+ switchedPerspective = yes;
+ spadDraw=yes;
+ break;
+
+ case region3D:
+ readViewman(&i1,intSize);
+ viewport->regionOn = i1;
+ viewData.box = i1;
+ spadDraw=yes;
+ if (viewport->haveControl) drawControlPanel();
+ redoSmooth = yes;
+ break;
+
+ case clipRegionOnOff:
+ readViewman(&i1,intSize);
+ viewData.clipbox = i1;
+ spadDraw=yes;
+ break;
+
+ case clipSurfaceOnOff:
+ readViewman(&i1,intSize);
+ viewData.clipStuff = i1;
+ spadDraw=yes;
+ break;
+
+ case eyeDistanceData:
+ readViewman(&f1,floatSize);
+ viewData.eyeDistance = f1;
+ if (viewData.eyeDistance > maxEyeDistance)
+ viewData.eyeDistance = maxEyeDistance;
+ else if (viewData.eyeDistance < minEyeDistance)
+ viewData.eyeDistance = minEyeDistance;
+ spadDraw=yes;
+ changedEyeDistance = yes;
+ break;
+
+ case hitherPlaneData:
+ readViewman(&f1,floatSize);
+ viewData.clipPlane = f1;
+ spadDraw=yes;
+ changedEyeDistance = yes;
+ break;
+
+ case colorDef:
+ readViewman(&(viewport->hueOffset),intSize);
+ readViewman(&(viewport->numberOfHues),intSize);
+ /* spadcolors is indexed by 0 */
+ viewport->hueOffset --;
+ viewport->numberOfHues --;
+ viewport->hueTop = viewport->numberOfHues;
+ if (viewport->hueOffset < 0) viewport->hueOffset = 0;
+ if (viewport->hueTop < 0) viewport->hueTop = 0;
+ if (viewport->hueOffset >= totalHues)
+ viewport->hueOffset = totalHues-1;
+ if (viewport->hueTop >= totalHues) viewport->hueTop = totalHues-1;
+ viewport->numberOfHues = viewport->hueTop - viewport->hueOffset;
+ if ((viewport->hueTop == viewport->hueOffset) && (!viewport->monoOn))
+ redoColor = yes;
+ else {
+ redoColor = no;
+ redoDither = yes;
+ }
+ if (viewport->haveControl) drawColorMap();
+ break;
+
+ case closeAll:
+ code = check(write(Socket,&ack,intSize));
+ goodbye(-1);
+
+
+ case moveViewport:
+ readViewman(&i1,intSize);
+ readViewman(&i2,intSize);
+ XMoveWindow(dsply,viewport->titleWindow,i1,i2);
+ XSync(dsply,0);
+ break;
+
+ case resizeViewport:
+ readViewman(&i1,intSize);
+ readViewman(&i2,intSize);
+ XResizeWindow(dsply,viewport->titleWindow,i1,i2+titleHeight);
+ XResizeWindow(dsply,viewport->viewWindow,i1,i2);
+ spadDraw=yes;
+ redoSmooth =yes;
+ break;
+
+ case transparent:
+ case opaqueMesh:
+ case render:
+ case smooth:
+ viewData.style = viewCommand;
+ spadDraw=yes;
+ redoSmooth =yes;
+ break;
+
+ case lightDef:
+ readViewman(&(viewport->lightVector[0]),floatSize);
+ readViewman(&(viewport->lightVector[1]),floatSize);
+ readViewman(&(viewport->lightVector[2]),floatSize);
+ normalizeVector(viewport->lightVector);
+ movingLight = yes;
+ drawLightingAxes();
+ XSync(dsply,0);
+ break;
+
+ case translucenceDef:
+ readViewman(&backLightIntensity,floatSize);
+ tempLightIntensity = backLightIntensity;
+ lightIntensity = tempLightIntensity;
+ changedIntensity = yes;
+ drawLightTransArrow();
+ XSync(dsply,0);
+ break;
+
+ case changeTitle:
+ readViewman(&i1,intSize);
+ readViewman(viewport->title,i1);
+ viewport->title[i1] = '\0';
+ writeTitle();
+ switch (doingPanel) {
+ case CONTROLpanel:
+ case CONTOURpanel:
+ writeControlTitle(control->controlWindow);
+ break;
+ case VOLUMEpanel:
+ writeControlTitle(volumeWindow);
+ break;
+ case LIGHTpanel:
+ writeControlTitle(lightingWindow);
+ break;
+ } /* switch */
+ XFlush(dsply);
+ break;
+
+ case writeView:
+ readViewman(&i1,intSize);
+ readViewman(filename,i1);
+ filename[i1] = '\0';
+ sprintf(errorStr,"writing of viewport data");
+ i3 = 0;
+ readViewman(&i2,intSize);
+ while (i2) {
+ i3 = i3 | (1<<i2);
+ readViewman(&i2,intSize);
+ }
+ if (writeViewport(i3) < 0)
+ fprintf(stderr," Nothing was written\n");
+ break;
+
+ case diagOnOff:
+ readViewman(&i1,intSize);
+ if (viewData.outlineRenderOn) {
+ viewport->diagonals = i1;
+ spadDraw=yes;
+ } else {
+ strcpy(control->message," Use this option with Outline ");
+ writeControlMessage();
+ }
+ break;
+
+ case outlineOnOff:
+ readViewman(&i1,intSize);
+ if (viewData.style == render) {
+ viewData.outlineRenderOn = i1;
+ spadDraw=yes;
+ if (viewport->haveControl) drawControlPanel();
+ } else {
+ strcpy(control->message," Use this option in Shaded mode ");
+ writeControlMessage();
+ }
+ break;
+
+ case spadPressedAButton:
+ readViewman(&i1,intSize);
+ buttonAction(i1);
+ break;
+ default:
+ return(-1);
+ } /* switch */
+
+
+ ack++;
+ code = check(write(Socket,&ack,intSize));
+ return(0);
+
+}
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/static.h b/src/graph/view3D/static.h
new file mode 100755
index 00000000..5f8b52d5
--- /dev/null
+++ b/src/graph/view3D/static.h
@@ -0,0 +1,61 @@
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+
+ /* This is a description of script character labels for the
+ x, y, and z axes */
+
+static float axes[3][6] = {{-117,0,0,117,0,0}, /* x axis */
+ {0,-117,0,0,117,0}, /* y axis */
+ {0,0,-117,0,0,117}}; /* z axis */
+
+/* text labels are currently used */
+static float labels[basicScreen][7] = {
+ {105,0,4,106,0,3,labelColor}, /* script x label - 4 segments */
+ {106,0,3,112,0,10,labelColor},
+ {112,0,10,114,0,9,labelColor},
+ {106,0,10,113,0,3,labelColor},
+ {0,106,9,0,107,10,labelColor}, /* script y label - 7 segments */
+ {0,107,10,0,107,6,labelColor},
+ {0,107,6,0,113,5,labelColor},
+ {0,113,10,0,113,-3,labelColor},
+ {0,113,-3,0,111,-5,labelColor},
+ {0,111,-5,0,110,-1,labelColor},
+ {0,110,-1,0,114,3,labelColor},
+ {0,5,114,0,6,115,labelColor}, /* script z label - 8 segments */
+ {0,6,115,0,11,116,labelColor},
+ {0,11,116,0,12,113,labelColor},
+ {0,12,113,0,10,111,labelColor},
+ {0,10,111,0,11,110,labelColor},
+ {0,11,110,0,11,103,labelColor},
+ {0,11,103,0,9,102,labelColor},
+ {0,9,102,0,9,105,labelColor}};
diff --git a/src/graph/view3D/stuff3d.c.pamphlet b/src/graph/view3D/stuff3d.c.pamphlet
new file mode 100644
index 00000000..f9ae2ff6
--- /dev/null
+++ b/src/graph/view3D/stuff3d.c.pamphlet
@@ -0,0 +1,201 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D stuff3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _STUFF3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include "header.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+
+
+
+#include "Gfun.H1"
+#include "spadcolors.H1"
+#include "util.H1"
+
+#include "all_3d.H1"
+/*****************************
+ *** traverse(n) ***
+ *** returns the nth point ***
+ *** in a point resevoir ***
+ *****************************/
+
+viewTriple *
+#ifdef _NO_PROTO
+traverse (n)
+ int n;
+#else
+traverse (int n)
+#endif
+{
+
+ int i;
+ viewTriple *v;
+
+ v = splitPoints;
+ for (i=0; i<n; i++) v = v->next;
+ return(v);
+
+} /* traverse */
+
+
+/**************************/
+/*** float absolute(x) ***/
+/**************************/
+
+float
+#ifdef _NO_PROTO
+absolute (x)
+ float x;
+#else
+absolute (float x)
+#endif
+{
+
+ if (x<0.0) return(-x);
+ else return(x);
+
+}
+
+
+
+
+/****************************/
+/*** float get_random(x) ***/
+/****************************/
+
+float
+#ifdef _NO_PROTO
+get_random()
+#else
+get_random(void)
+#endif
+{
+
+ float x;
+
+ x = (float)(rand() % 100);
+ return(x);
+
+}
+
+
+
+
+/****************************/
+/*** float norm_dist() ***/
+/****************************/
+
+triple
+#ifdef _NO_PROTO
+norm_dist()
+#else
+norm_dist(void)
+#endif
+{
+
+ float u1, u2, v1, v2, ss, rad;
+ triple pert;
+
+ ss = 2.0;
+ while (ss >= 1.0) {
+ u1 = get_random()/100.0;
+ u2 = get_random()/100.0;
+ v1 = 2.0*u1 - 1.0; v2 = 2.0*u2 - 1.0;
+ ss = v1*v1 + v2*v2;
+ }
+ if (ss == 0.0) ss += .1;
+ rad = -2.0*log(ss)/ss;
+ pert.x = v1 * sqrt(rad);
+ pert.y = v2 * sqrt(rad);
+
+ return(pert);
+}
+
+
+
+/************************/
+/*** void goodbye() ***/
+/************************/
+
+void
+#ifdef _NO_PROTO
+goodbye(sig)
+int sig;
+#else
+goodbye(int sig)
+#endif
+{
+
+ int Command;
+
+ PSClose(); /* free PS file and data structure space */
+
+ if (pixelSetFlag) FreePixels(dsply,colorMap,smoothConst);
+ if (!viewAloned) {
+ Command = viewportClosing;
+ check(write(Socket,&Command,intSize));
+ }
+
+ XCloseDisplay(dsply);
+ exit(0);
+} /* goodbye */
+
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/surface3d.c.pamphlet b/src/graph/view3D/surface3d.c.pamphlet
new file mode 100644
index 00000000..cb2bacc4
--- /dev/null
+++ b/src/graph/view3D/surface3d.c.pamphlet
@@ -0,0 +1,870 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D surface3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _SURFACE3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include <string.h>
+#include <math.h>
+#include <stdlib.h>
+
+#include "header.h"
+#include "draw.h"
+#include "mode.h" /* for #define components */
+#include "com.h"
+
+#include "XSpadFill.H1"
+#include "XShade.H1"
+#include "util.H1"
+#include "Gfun.H1"
+#include "all_3d.H1"
+
+
+ /**** useful defines ****/
+
+#define precisionFactor 1024
+
+/* depthChecker turns on the extensive depth checking mechanisms
+ for the depth sort algorithm. Without it, the hidden surface
+ removal is just a sort by z which works remarkably well, but,
+ is insufficient and, at times, may end up being incorrect */
+#define depthChecker
+
+
+pointInfo ptIA, ptIB, ptIC; /* global to this file */
+
+/************************************
+ * void drawLineComponent(p,dFlag) *
+ ************************************/
+
+void
+#ifdef _NO_PROTO
+drawLineComponent (p, dFlag)
+ poly *p;
+ int dFlag;
+#else
+drawLineComponent (poly * p, int dFlag)
+#endif
+{
+ int i, hue;
+ int *anIndex;
+ RGB col_rgb;
+
+ /* If the polygon is clipped against the hither plane (clipPz) then
+ it is not drawn...or...if the clipStuff is set to true, and
+ the polygon is clipped against the user defined clip volume, it
+ is also not drawn. */
+ if (!((p->partialClipPz) || (viewData.clipStuff && (p->partialClip)))) {
+ /* This routine will eventually only be skipped if
+ p->totalClip is true and another routine would
+ handle the partialClip. this routine would handle
+ only those polygons without any clipped points */
+ for (i=0, anIndex=p->indexPtr; i<p->numpts; i++,anIndex++) {
+ quadMesh[i].x = refPt3D(viewData,*anIndex)->px;
+ quadMesh[i].y = refPt3D(viewData,*anIndex)->py;
+ }
+
+ if (dFlag==Xoption) {
+ if (mono || viewport->monoOn)
+ GSetForeground(opaqueGC, (float)foregroundColor, dFlag);
+ else {
+ hue = hueValue(p->color);
+ GSetForeground(opaqueGC, (float)XSolidColor(hue,2), dFlag);
+ }
+ } else
+ GSetForeground(opaqueGC, psBlack, dFlag);
+
+ if (dFlag==PSoption && !mono && !viewport->monoOn) {
+ hue = getHue(p->color);
+ col_rgb = hlsTOrgb((float)hue,0.5,0.8);
+ PSDrawColor(col_rgb.r,col_rgb.g,col_rgb.b,quadMesh,p->numpts);
+ } else {
+ GDrawLines(opaqueGC, viewport->viewWindow, quadMesh, p->numpts,
+ CoordModeOrigin, dFlag);
+ }
+ if (dFlag == Xoption)
+ XMapWindow(dsply, viewport->viewWindow);
+ }
+}
+
+
+
+/**************************************************
+ * void drawOpaquePolygon(p,aGC,anotherGC) *
+ **************************************************/
+
+void
+#ifdef _NO_PROTO
+drawOpaquePolygon (p,aGC,anotherGC,dFlag)
+ poly *p;
+ GC aGC,anotherGC;
+ int dFlag;
+#else
+drawOpaquePolygon (poly *p,GC aGC,GC anotherGC,int dFlag)
+#endif
+{
+
+ int *anIndex, i, hue, isNaN = 0;
+ RGB col_rgb;
+
+ if (mono || viewport->monoOn) {
+ GSetForeground(anotherGC, (float)foregroundColor, dFlag);
+ } else {
+ hue = hueValue(p->color);
+ GSetForeground(anotherGC, (float)XSolidColor(hue,2), dFlag);
+ }
+
+ /* If the polygon is clipped against the hither plane (clipPz) then
+ it is not drawn, or if the clipStuff is set to true, and
+ the polygon is clipped against the user defined clip volume, it
+ is also not drawn. */
+
+ if (!((p->partialClipPz) || (viewData.clipStuff && (p->partialClip)))) {
+
+ /* This routine should eventually only be skipped if
+ p->totalClip is true and another routine would
+ handle the partialClip. This routine would handle
+ only those polygons without any clipped points. */
+
+ for (i=0, anIndex=p->indexPtr; i<p->numpts; i++,anIndex++) {
+ quadMesh[i].x = refPt3D(viewData,*anIndex)->px;
+ quadMesh[i].y = refPt3D(viewData,*anIndex)->py;
+ if (eqNANQ(quadMesh[i].x) || eqNANQ(quadMesh[i].y)) isNaN = 1;
+ }
+
+ quadMesh[i].x =refPt3D(viewData,*(p->indexPtr))->px;
+ quadMesh[i].y =refPt3D(viewData,*(p->indexPtr))->py;
+ if (eqNANQ(quadMesh[i].x) || eqNANQ(quadMesh[i].y)) isNaN = 1;
+
+ if (dFlag==PSoption && !mono && !viewport->monoOn && !isNaN) {
+ GSetForeground(GC9991, (float)backgroundColor, PSoption);
+ PSFillPolygon(GC9991, quadMesh, p->numpts+1);
+ hue = getHue(p->color);
+ col_rgb = hlsTOrgb((float)hue,0.5,0.8);
+ if (viewport->diagonals)
+ PSDrawColor(col_rgb.r,col_rgb.g,col_rgb.b,quadMesh,p->numpts+1);
+ else
+ PSDrawColor(col_rgb.r,col_rgb.g,col_rgb.b,quadMesh,p->numpts);
+ } else {
+ if (mono || viewport->monoOn) {
+ GSetForeground(anotherGC, (float)foregroundColor, dFlag);
+ } else {
+ hue = hueValue(p->color);
+ GSetForeground(anotherGC, (float)XSolidColor(hue,2), dFlag);
+ }
+ GSetForeground(aGC,(float)backgroundColor,dFlag);
+ if (!isNaN) {
+ XFillPolygon(dsply, viewport->viewWindow, aGC, quadMesh, p->numpts,
+ Convex,CoordModeOrigin);
+ if (viewport->diagonals)
+ GDrawLines(anotherGC,viewport->viewWindow,quadMesh,p->numpts+1,
+ CoordModeOrigin, dFlag);
+ else
+ GDrawLines(anotherGC,viewport->viewWindow,quadMesh,p->numpts,
+ CoordModeOrigin, dFlag);
+ }
+ }
+ if (dFlag == Xoption) XMapWindow(dsply,viewport->viewWindow);
+ } /* if not totally clipped */
+}
+
+
+
+/*************************************
+ * poly *copyPolygons(polygonList) *
+ * *
+ * copies the given list of polygons *
+ * into a newly allocated list *
+ *************************************/
+
+poly *
+#ifdef _NO_PROTO
+copyPolygons (polygonList)
+ poly *polygonList;
+#else
+copyPolygons (poly *polygonList)
+#endif
+{
+
+ int i;
+ poly *aPoly,*retval,*prev;
+
+ prev = retval = aPoly = (poly *)saymem("surface.c",1,sizeof(poly));
+ aPoly->indexPtr = (int *)saymem("surface.c",
+ polygonList->numpts,sizeof(int));
+ aPoly->num = polygonList->num;
+ aPoly->sortNum = polygonList->sortNum;
+ aPoly->split = polygonList->split;
+ aPoly->numpts = polygonList->numpts;
+ for (i=0; i<aPoly->numpts; i++)
+ *((aPoly->indexPtr) + i) = *((polygonList->indexPtr) + i);
+ aPoly->N[0] = polygonList->N[0];
+ aPoly->N[1] = polygonList->N[1];
+ aPoly->N[2] = polygonList->N[2];
+ aPoly->planeConst = polygonList->planeConst;
+ aPoly->color = polygonList->color;
+ aPoly->moved = no;
+ aPoly->pxmin = polygonList->pxmin;
+ aPoly->pxmax = polygonList->pxmax;
+ aPoly->pymin = polygonList->pymin;
+ aPoly->pymax = polygonList->pymax;
+ aPoly->pzmin = polygonList->pzmin;
+ aPoly->pzmax = polygonList->pzmax;
+ aPoly->xmin = polygonList->xmin;
+ aPoly->xmax = polygonList->xmax;
+ aPoly->ymin = polygonList->ymin;
+ aPoly->ymax = polygonList->ymax;
+ aPoly->zmin = polygonList->zmin;
+ aPoly->zmax = polygonList->zmax;
+ aPoly->normalFacingOut = polygonList->normalFacingOut;
+ aPoly->primitiveType = polygonList->primitiveType;
+ for (polygonList = polygonList->next;
+ polygonList != NIL(poly);
+ polygonList = polygonList->next) {
+ prev->next = aPoly = (poly *)saymem("surface.c",1,sizeof(poly));
+ aPoly->indexPtr = (int *)saymem("surface.c",
+ polygonList->numpts,sizeof(int));
+ aPoly->num = polygonList->num;
+ aPoly->sortNum = polygonList->sortNum;
+ aPoly->numpts = polygonList->numpts;
+ aPoly->split = polygonList->split;
+ for (i=0; i<aPoly->numpts; i++)
+ *((aPoly->indexPtr) + i) = *((polygonList->indexPtr) + i);
+ aPoly->N[0] = polygonList->N[0];
+ aPoly->N[1] = polygonList->N[1];
+ aPoly->N[2] = polygonList->N[2];
+ aPoly->planeConst = polygonList->planeConst;
+ aPoly->color = polygonList->color;
+ aPoly->moved = no;
+ aPoly->pxmin = polygonList->pxmin;
+ aPoly->pxmax = polygonList->pxmax;
+ aPoly->pymin = polygonList->pymin;
+ aPoly->pymax = polygonList->pymax;
+ aPoly->pzmin = polygonList->pzmin;
+ aPoly->pzmax = polygonList->pzmax;
+ aPoly->xmin = polygonList->xmin;
+ aPoly->xmax = polygonList->xmax;
+ aPoly->ymin = polygonList->ymin;
+ aPoly->ymax = polygonList->ymax;
+ aPoly->zmin = polygonList->zmin;
+ aPoly->zmax = polygonList->zmax;
+ aPoly->normalFacingOut = polygonList->normalFacingOut;
+ aPoly->primitiveType = polygonList->primitiveType;
+ prev = aPoly;
+ }
+ aPoly->next = 0;
+ return(retval);
+}
+
+
+/******************************
+ * void minMaxPolygons(aPoly) *
+ * *
+ * sets up the xmin, *
+ * etc, for each polygon *
+ * for sorting and *
+ * extent checking. *
+ ******************************/
+
+void
+#ifdef _NO_PROTO
+minMaxPolygons (aPoly)
+ poly *aPoly;
+#else
+minMaxPolygons (poly *aPoly)
+#endif
+{
+
+ int *anIndex;
+ int i;
+
+ for (; aPoly != NIL(poly); aPoly = aPoly->next) {
+ anIndex = aPoly->indexPtr;
+ aPoly->pxmin = aPoly->pxmax = refPt3D(viewData,*anIndex)->px;
+ aPoly->pymin = aPoly->pymax = refPt3D(viewData,*anIndex)->py;
+ aPoly->pzmin = aPoly->pzmax = refPt3D(viewData,*anIndex)->pz;
+ aPoly->xmin = aPoly->xmax = refPt3D(viewData,*anIndex)->x;
+ aPoly->ymin = aPoly->ymax = refPt3D(viewData,*anIndex)->y;
+ aPoly->zmin = aPoly->zmax = refPt3D(viewData,*anIndex)->z;
+ for (i=1,anIndex++; i<aPoly->numpts; i++,anIndex++) {
+ if (refPt3D(viewData,*anIndex)->px < aPoly->pxmin)
+ aPoly->pxmin = refPt3D(viewData,*anIndex)->px;
+ else if (refPt3D(viewData,*anIndex)->px > aPoly->pxmax)
+ aPoly->pxmax = refPt3D(viewData,*anIndex)->px;
+ if (refPt3D(viewData,*anIndex)->py < aPoly->pymin)
+ aPoly->pymin = refPt3D(viewData,*anIndex)->py;
+ else if (refPt3D(viewData,*anIndex)->py > aPoly->pymax)
+ aPoly->pymax = refPt3D(viewData,*anIndex)->py;
+ if (refPt3D(viewData,*anIndex)->pz < aPoly->pzmin)
+ aPoly->pzmin = refPt3D(viewData,*anIndex)->pz;
+ else if (refPt3D(viewData,*anIndex)->pz > aPoly->pzmax)
+ aPoly->pzmax = refPt3D(viewData,*anIndex)->pz;
+
+ if (refPt3D(viewData,*anIndex)->x < aPoly->xmin)
+ aPoly->xmin = refPt3D(viewData,*anIndex)->x;
+ else if (refPt3D(viewData,*anIndex)->x > aPoly->xmax)
+ aPoly->xmax = refPt3D(viewData,*anIndex)->x;
+ if (refPt3D(viewData,*anIndex)->y < aPoly->ymin)
+ aPoly->ymin = refPt3D(viewData,*anIndex)->y;
+ else if (refPt3D(viewData,*anIndex)->y > aPoly->ymax)
+ aPoly->ymax = refPt3D(viewData,*anIndex)->y;
+ if (refPt3D(viewData,*anIndex)->z < aPoly->zmin)
+ aPoly->zmin = refPt3D(viewData,*anIndex)->z;
+ else if (refPt3D(viewData,*anIndex)->z > aPoly->zmax)
+ aPoly->zmax = refPt3D(viewData,*anIndex)->z;
+ }
+ }
+} /* minMaxPolygons */
+
+
+
+/***********************************
+ * int polyCompare (p1,p2) *
+ * *
+ * returns -1 if p1 < p2 *
+ * 0 if p1 = p2 *
+ * 1 if p1 > p2 *
+ * note that this is the reverse *
+ * of what the msort requested. *
+ * this is so that the list will *
+ * be sorted from max to min. *
+ ***********************************/
+
+int
+#ifdef _NO_PROTO
+polyCompare (p1,p2)
+ poly *p1,*p2;
+#else
+polyCompare (poly *p1,poly *p2)
+#endif
+{
+
+ if (p1->pzmax > p2->pzmax) return(-1);
+ else if (p1->pzmax < p2->pzmax) return(1);
+ else return(0);
+}
+
+/***********************
+ * void calcEyePoint() *
+ * *
+ * sets the global *
+ * variable eyePoint[] *
+ * to where the viewer *
+ * is pointed towards *
+ ***********************/
+
+void
+#ifdef _NO_PROTO
+calcEyePoint ()
+#else
+calcEyePoint (void)
+#endif
+{
+
+ eyePoint[0] = sinPhi * (sinTheta);
+ eyePoint[1] = sinPhi * (-cosTheta);
+ eyePoint[2] = cosPhi;
+
+}
+
+
+
+/*
+ void drawPolygons()
+ A general routine for displaying a list of polygons
+ with the proper hidden surfaces removed. Assumes the
+ list of polygons is in viewData.polygons. Needs a
+ routine to split intersecting polygons in object space. *
+ */
+
+
+/**************************************
+ * void drawRenderedPolygon(p,dFlag) *
+ * *
+ * calculate the color for the *
+ * polygon p and draw it *
+ **************************************/
+
+void
+#ifdef _NO_PROTO
+drawRenderedPolygon (p,dFlag)
+ poly *p;
+ int dFlag;
+#else
+drawRenderedPolygon (poly *p,int dFlag)
+#endif
+{
+
+ int i,hue,shade, isNaN = 0;
+ float whichSide,H[3],P[3],LN,HN,diff,spec,tempLight,lumens,E[3],N[3];
+ int *anIndex, *indx;
+ RGB col_rgb;
+
+ if (!((p->partialClipPz) || (viewData.clipStuff && (p->partialClip)))) {
+ /* This routine should eventually only be skipped if
+ p->totalClip is true and another routine would
+ handle the partialClip. This routine would handle
+ only those polygons without any clipped points. */
+
+ for (i=0, anIndex=p->indexPtr; i<p->numpts; i++,anIndex++) {
+ quadMesh[i].x = refPt3D(viewData,*anIndex)->px;
+ quadMesh[i].y = refPt3D(viewData,*anIndex)->py;
+ if (eqNANQ(quadMesh[i].x) || eqNANQ(quadMesh[i].y)) isNaN = 1;
+ }
+ quadMesh[i].x = refPt3D(viewData,*(p->indexPtr))->px;
+ quadMesh[i].y = refPt3D(viewData,*(p->indexPtr))->py;
+ if (eqNANQ(quadMesh[i].x) || eqNANQ(quadMesh[i].y)) isNaN = 1;
+
+ if (!isNaN) {
+ /* calculate polygon illumination */
+ indx = p->indexPtr;
+ P[0] = (refPt3D(viewData,*(indx))->wx +
+ refPt3D(viewData,*(indx+1))->wx +
+ refPt3D(viewData,*(indx+2))->wx);
+ P[1] = (refPt3D(viewData,*(indx))->wy +
+ refPt3D(viewData,*(indx+1))->wy +
+ refPt3D(viewData,*(indx+2))->wy);
+ P[2] = (refPt3D(viewData,*(indx))->wz +
+ refPt3D(viewData,*(indx+1))->wz +
+ refPt3D(viewData,*(indx+2))->wz);
+ normalizeVector(P);
+
+ N[0] = p->N[0]; N[1] = p->N[1]; N[2] = p->N[2];
+ normalizeVector(eyePoint);
+ E[0] = 4.0*eyePoint[0] - P[0];
+ E[1] = 4.0*eyePoint[1] - P[1];
+ E[2] = 4.0*eyePoint[2] - P[2];
+ normalizeVector(E);
+ diff = 0.0; spec = 0.0;
+ LN = N[0]*viewport->lightVector[0] +
+ N[1]*viewport->lightVector[1] +
+ N[2]*viewport->lightVector[2];
+ if (LN < 0.0) LN = -LN;
+ diff = LN*Cdiff;
+
+ if (LN > 0.0) {
+ H[0] = E[0] + viewport->lightVector[0];
+ H[1] = E[1] + viewport->lightVector[1];
+ H[2] = E[2] + viewport->lightVector[2];
+ normalizeVector(H);
+ HN = dotProduct(N,H,3);
+ if (HN < 0.0) HN = -HN;
+ spec = pow((double)absolute(HN),coeff);
+ if (spec > 1.0) spec = 1.0;
+ }
+
+ lumens = ((Camb + 0.15) + diff + spec*Cspec);
+ if (lumens > 1.0) lumens = 1.0;
+ if (lumens < 0.0) lumens = 0.0;
+ if (dFlag==PSoption && !mono && !viewport->monoOn) {
+ hue = getHue(p->color);
+ col_rgb = hlsTOrgb((float)hue,lumens,0.8);
+ /* NTSC color to grey = .299 red + .587 green + .114 blue */
+ maxGreyShade = (int) psShadeMax;
+ whichSide = (.299*col_rgb.r + .587*col_rgb.g + .114*col_rgb.b) *
+ (maxGreyShade-1);
+ }
+ else {
+ if (mono || viewport->monoOn) {
+ hue = getHue(p->color);
+ col_rgb = hlsTOrgb((float)hue,lumens,0.8);
+ whichSide = (.299*col_rgb.r + .587*col_rgb.g + .114*col_rgb.b) *
+ (maxGreyShade-1);
+ } else
+ whichSide = lumens*(totalShades-1);
+ }
+
+ tempLight = lightIntensity;
+ if (lightIntensity < Camb) lightIntensity = Camb;
+
+ shade = floor(lightIntensity * absolute(whichSide));
+ lightIntensity = tempLight;
+
+ if (shade < totalShades) {
+ /* shade < totalShades is (temporarily) necessary here
+ because, currently, parameterizations for things like
+ the sphere would produce triangular shaped polygons
+ close to the poles which get triangularized leaving a
+ triangle with coincidental points. the normal for this
+ would be undefined (since coincidental points would create
+ a zero vector) and the shade would be large, hence,
+ the conditional. */
+
+ if (mono || viewport->monoOn) {
+ if (dFlag == Xoption) {
+ XChangeShade(dsply,maxGreyShade-shade-1);
+ XShadePolygon(dsply,viewport->viewWindow,quadMesh,p->numpts+1,
+ Convex,CoordModeOrigin);
+ }
+ else if (dFlag == PSoption) { /* renderGC has number 9991
+ (see main.c, header.h) */
+ GSetForeground(GC9991,
+ 1.0-(float)(maxGreyShade-shade-1)*psShadeMul,PSoption);
+ PSFillPolygon(GC9991, quadMesh, p->numpts+1);
+ }
+ } else { /* not mono */
+ if (dFlag == Xoption) {
+ hue = hueValue(p->color);
+ XSpadFillPolygon(dsply, viewport->viewWindow, quadMesh,
+ p->numpts+1, Convex,CoordModeOrigin, hue, shade);
+ }
+ else if (dFlag == PSoption) /* draws it out in monochrome */
+ PSColorPolygon(col_rgb.r,col_rgb.g,col_rgb.b,quadMesh,p->numpts+1);
+ } /* if mono-else */
+
+ if (viewData.outlineRenderOn) {
+ if (viewport->diagonals) {
+ if (dFlag == PSoption) {
+ GSetForeground(renderGC,psBlack, dFlag);
+ GDrawLines(renderGC,viewport->viewWindow,quadMesh,p->numpts+1,
+ CoordModeOrigin,dFlag);
+ } else
+ GDrawLines(renderGC,viewport->viewWindow,quadMesh,p->numpts+1,
+ CoordModeOrigin,dFlag);
+ } else {
+ if (dFlag == PSoption) {
+ GSetForeground(renderGC,psBlack,PSoption);
+ GDrawLines(renderGC,viewport->viewWindow,quadMesh,p->numpts,
+ CoordModeOrigin,PSoption);
+ } else
+ GDrawLines(renderGC,viewport->viewWindow,quadMesh,p->numpts,
+ CoordModeOrigin,dFlag);
+ }
+ }
+ }
+ } /* if not NaN */
+ if (dFlag == Xoption) XMapWindow(dsply,viewport->viewWindow);
+ } /* if not clipped */
+
+} /* drawRenderedPolygon */
+
+
+void
+#ifdef _NO_PROTO
+freePointResevoir()
+#else
+freePointResevoir(void)
+#endif
+{
+
+ viewTriple *v;
+
+ while (splitPoints != NIL(viewTriple)) {
+ v = splitPoints;
+ splitPoints = splitPoints->next;
+ free(v);
+ }
+
+} /* freePointResevoir */
+
+/***********************************
+ * void freeListOfPolygons(pList); *
+ * *
+ * frees up a list of polygons. *
+ ***********************************/
+
+void
+#ifdef _NO_PROTO
+freeListOfPolygons (pList)
+poly *pList;
+#else
+freeListOfPolygons (poly *pList)
+#endif
+{
+
+ poly *nextP;
+
+ for (; pList != NIL(poly); pList=nextP) {
+ nextP=pList->next;
+ free(pList->indexPtr);
+ free(pList);
+ }
+} /* freeListOfPolygons() */
+
+
+
+void
+#ifdef _NO_PROTO
+drawPolygons(dFlag)
+ int dFlag;
+#else
+drawPolygons(int dFlag)
+#endif
+{
+
+ poly *p,*head;
+ poly *tempQuick=NULL;
+ int quickFirst=yes;
+
+ if (recalc) {
+
+ /* To get around multiple X Expose events the server tends
+ to send upon startup, leave negation of firstTime to the end. */
+ rotated = no;
+ zoomed = no;
+ translated = no;
+ switchedPerspective = no;
+ changedEyeDistance = no;
+ redoSmooth = yes;
+
+ if (keepDrawingViewport()) {
+ if (!firstTime) {
+ strcpy(control->message," Creating Polygons ");
+ writeControlMessage();
+ freeListOfPolygons(quickList);
+ freePointResevoir();
+ }
+ strcpy(control->message," Collecting Polygons ");
+ writeControlMessage();
+ quickList = copyPolygons(viewData.polygons);
+
+ if (keepDrawingViewport()) {
+ /* to get normal facing outside info */
+ strcpy(control->message," Projecting Polygons ");
+ writeControlMessage();
+ projectAllPolys(quickList);
+ if (keepDrawingViewport()) {
+ strcpy(control->message," Setting Extreme Values ");
+ writeControlMessage();
+ minMaxPolygons(quickList);
+ if (keepDrawingViewport()) {
+ strcpy(control->message," Sorting Polygons ");
+ writeControlMessage();
+ quickList = msort(quickList,0,viewData.numPolygons,polyCompare);
+ if (keepDrawingViewport()) {
+ calcEyePoint();
+ head = p = quickList;
+
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+
+ if (viewData.scaleDown) {
+ if (keepDrawingViewport()) {
+ for (p=quickList;
+ keepDrawingViewport() && (p != NIL(poly));
+ p=p->next) {
+ switch (p->primitiveType) {
+ case pointComponent:
+ if (dFlag==Xoption) {
+ if (mono || viewport->monoOn)
+ GSetForeground(componentGC,
+ (float)foregroundColor, dFlag);
+ else
+ GSetForeground(componentGC,
+ (float)meshOutline, dFlag);
+ } else {
+ GSetForeground(componentGC, psBlack, dFlag);
+ GFillArc(componentGC, viewport->viewWindow,
+ (int)refPt3D(viewData,*(p->indexPtr))->px,
+ (int)refPt3D(viewData,*(p->indexPtr))->py,
+ viewData.pointSize,viewData.pointSize,0,
+ 360*64, dFlag);
+ }
+ break;
+ case lineComponent:
+ drawLineComponent(p,dFlag);
+ break;
+ default:
+ if (viewData.style == opaqueMesh) {
+ GSetForeground(globGC,(float)backgroundColor,dFlag);
+ drawOpaquePolygon(p,globGC,opaqueGC,dFlag);
+ } else {
+ drawRenderedPolygon(p,dFlag);
+ }
+ } /* switch */
+ }
+ }
+ }
+
+ if (!quickFirst) {
+ /* append the rest of the polygons onto the list */
+ tempQuick->next = head;
+ /* but do not continue the drawing... */
+ if (head != NIL(poly)) head->doNotStopDraw = no;
+ } /* if !quickFirst */
+ finishedList = (p==NIL(poly));
+ } /* for various */
+ } /* steps */
+ } /* of */
+ } /* keepDrawingViewport() */
+ } /* *** */
+ /* May want to have a flag somewhere to stop the drawing yet
+ continue the freeing */
+ if (firstTime) firstTime = no;
+ } else { /* if recalc else if not recalc just draw stuff in list */
+ if (keepDrawingViewport()) {
+ for (p=quickList;
+ keepDrawingViewport() && p != NIL(poly) &&
+ (viewData.scaleDown || p->doNotStopDraw); p=p->next) {
+ projectAPoly(p);
+ switch (p->primitiveType) {
+ case pointComponent:
+ if (dFlag==Xoption) {
+ if (mono || viewport->monoOn)
+ GSetForeground(componentGC,(float)foregroundColor, dFlag);
+ else
+ GSetForeground(componentGC,(float)meshOutline, dFlag);
+ } else
+ GSetForeground(componentGC,psBlack, dFlag);
+ GFillArc(componentGC, viewport->viewWindow,
+ (int)refPt3D(viewData,*(p->indexPtr))->px,
+ (int)refPt3D(viewData,*(p->indexPtr))->py,
+ viewData.pointSize,viewData.pointSize,0,360*64,dFlag);
+ break;
+ case lineComponent:
+ drawLineComponent(p,dFlag);
+ break;
+ default:
+ if (viewData.style == opaqueMesh) {
+ GSetForeground(globGC,(float)backgroundColor,dFlag);
+ drawOpaquePolygon(p,globGC,opaqueGC,dFlag);
+ } else
+ drawRenderedPolygon(p,dFlag);
+ } /* switch */
+ }
+ }
+ }
+} /* drawPolygons */
+
+
+
+
+
+
+
+/**************************
+ * int lessThan(x,y) *
+ * int greaterThan(x,y) *
+ * int equal(x,y) *
+ * *
+ * Compares two floating *
+ * point numbers for *
+ * precision of up to one *
+ * place in a thousand. *
+ * returns *
+ * 1 if true *
+ * o otherwise *
+ **************************/
+
+int
+#ifdef _NO_PROTO
+lessThan (x,y)
+ float x,y;
+#else
+lessThan (float x,float y)
+#endif
+{
+ int xI,yI;
+
+ xI = x*precisionFactor;
+ yI = y*precisionFactor;
+ return(xI<yI);
+}
+
+int
+#ifdef _NO_PROTO
+greaterThan (x,y)
+ float x,y;
+#else
+greaterThan (float x,float y)
+#endif
+{
+ int xI,yI;
+
+ xI = x*precisionFactor;
+ yI = y*precisionFactor;
+ return(xI>yI);
+}
+
+int
+#ifdef _NO_PROTO
+isNaN (v)
+ float v;
+#else
+isNaN (float v)
+#endif
+{
+ return (v != v);
+}
+
+
+int
+#ifdef _NO_PROTO
+isNaNPoint (x,y,z)
+ float x,y,z;
+#else
+isNaNPoint (float x,float y,float z)
+#endif
+{
+ return (isNaN(x) || isNaN(y) || isNaN(z));
+}
+
+int
+#ifdef _NO_PROTO
+equal (x,y)
+ float x,y;
+#else
+equal (float x,float y)
+#endif
+{
+ int xI,yI;
+
+ xI = x*precisionFactor;
+ yI = y*precisionFactor;
+ return(xI==yI);
+}
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/testcol.c.pamphlet b/src/graph/view3D/testcol.c.pamphlet
new file mode 100644
index 00000000..64e8ab4b
--- /dev/null
+++ b/src/graph/view3D/testcol.c.pamphlet
@@ -0,0 +1,623 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D testcol.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _MAIN3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <math.h>
+
+#include "header.h"
+#include "cpanel.h"
+#include "process.h"
+#include "bsdsignal.h"
+
+#include "bsdsignal.H1"
+#include "util.H1"
+#include "Gfun.H1"
+#include "XSpadFill.H1"
+#include "XShade.H1"
+#include "all_3d.H1"
+
+#include "spadBitmap.bitmap"
+#include "spadMask.mask"
+
+viewPoints *viewport;
+GCptr GChead=NULL; /* ptr to head of ps GC linked list */
+char *PSfilename; /* output file name used in user directory */
+int psInit=no; /* need to call globaInitPs() each run */
+char *envAXIOM; /* used for ps file paths */
+int maxGreyShade=0;
+GC globalGC1, globalGC2, anotherGC, globGC, trashGC,
+ controlMessageGC, lightingGC, volumeGC, quitGC, processGC,
+ saveGC, graphGC, componentGC, opaqueGC, renderGC;
+unsigned long foregroundColor, backgroundColor;
+int Socket=1, ack=1;
+Colormap colorMap;
+viewTriple *splitPoints;
+Display *dsply;
+int scrn;
+Window rtWindow;
+HashTable *table;
+int mono, totalColors, totalSolid, totalDithered, totalHues,
+ totalSolidShades, totalDitheredAndSolids,totalShades;
+XFontStruct *globalFont, *buttonFont, *headerFont, *titleFont, *graphFont,
+ *lightingFont, *volumeFont, *quitFont, *saveFont,*serverFont;
+XGCValues gcVals;
+unsigned long * spadColors;
+float transform[4][4], transform1[4][4],
+ R[4][4], R1[4][4], S[4][4], T[4][4], I[4][4];
+float A[4][4], B[4][4], D[4], E[4][4], F[4], array[4][4];
+
+int followMouse=no,
+ viewportKeyNum=0;
+ /**********************/
+ /** global variables **/
+ /**********************/
+
+char scaleReport[5];
+char deltaXReport[5], deltaYReport[5];
+XSizeHints viewSizeHints;
+
+GC processGC;
+viewPoints *viewport;
+controlPanelStruct *control;
+char *s;
+int someInt;
+
+/* check /usr/include/X11 for current implementation of
+ pixels (e.g. BlackPixel()) */
+
+ /** totalShades is initially set to totalShadesConst.
+ If X cannot allocate 8 shades for each hue, total-
+ Shades is decremented. there is currently only a check for
+ this value to be positive. --> something to add: change over
+ to monochrome if totalShades=0. just modify the spadcolors.c
+ file. spadcolors.c has been modified so that it returns the
+ value for totalShades. since the return value had previously
+ been unused, a modification in this way ensures continued
+ support of other routines calling this function (e.g.
+ hypertex stuff). **/
+
+
+int drawMore;
+
+int spadMode=no, /* yes if receiving AXIOM command and
+ calling drawViewport */
+ spadDraw=no; /* yes if drawing viewport for
+ an AXIOM command */
+int spadSignalReceived=0; /* yes if current state is a result of
+ a signal from AXIOM */
+int inNextEvent=no; /* true just before a call to
+ XNextEvent */
+jmp_buf jumpFlag;
+
+char errorStr[80];
+
+view3DStruct viewData;
+
+Window quitWindow, saveWindow;
+
+ /** variables below assume only one viewport per process **/
+
+Window lightingWindow, lightingAxes;
+float lightPointer[3], tempLightPointer[3];
+
+int axesXY[3][4];
+float axesZ[3][2];
+
+float lightIntensity=1.0, tempLightIntensity;
+float backLightIntensity = 1.0;
+
+ /** used for writing viewport info out to a file **/
+char filename[256];
+
+
+ /** used for draw viewport routines */
+float sinTheta, sinPhi, cosTheta, cosPhi, viewScale,
+ viewScaleX, viewScaleY, viewScaleZ, reScale;
+int xCenter, yCenter;
+
+XWindowAttributes vwInfo;
+XWindowAttributes graphWindowAttrib;
+
+XPoint *quadMesh;
+XImage *imageX;
+int *xPts; /* pointer to projected points (x followed by y) */
+float transform[4][4], transform1[4][4],
+ R[4][4], R1[4][4], S[4][4], T[4][4], I[4][4];
+float A[4][4], B[4][4], D[4], E[4][4], F[4], array[4][4];
+
+
+int scanline, polyCount;
+polyList *scanList[ARRAY_HEIGHT];
+float xleft = (float)0 ,xright = (float)ARRAY_WIDTH;
+
+colorBuffer cBuffer[ARRAY_WIDTH];
+float zBuffer[ARRAY_WIDTH];
+
+float zC, dzdx, lum, point_norm[3];
+float intersectColor[2], dcolor;
+triple dpt, dnorm;
+
+ /** eyePoint **/
+float eyePoint[3];
+
+ /** tube stuff **/
+XPoint polygonMesh[20];
+
+ /* bypass the hidden surface algorithm if no rotations, etc */
+int saveFlag=no;
+int firstTime=yes, noTrans = yes, startup = yes;
+int redrawView = no; /* set to yes when returning from
+ subpanels */
+int redoColor = no, pixelSetFlag = no, redoDither = no;
+int redoSmooth = no, multiColorFlag = no;
+
+/* In order to set recalc to true (see draw.h) */
+int finishedList=no, zoomed=yes, translated = yes,
+ changedIntensity, movingLight = no, writeImage = no,
+ rotated=yes, switchedPerspective, changedEyeDistance,
+ gotToggle = no;
+poly *quickList;
+
+ /** if not connected to AXIOM **/
+int viewAloned;
+
+ /** for drawing the box **/
+viewTriple corners[8], clipCorners[8];
+boxSideStruct box[6], clipBox[6];
+
+ /** for freeing up points created frrom split polygons **/
+int resMax=0; /* number of points in the split point resevoir */
+
+ /** view volume stuff **/
+Window volumeWindow;
+int frustrumVertex;
+int doingPanel=CONTROLpanel; /* rewrite titles in proper panel */
+int doingVolume;
+
+int screenX; /* global floating point indicating mouse position
+ on frustrum screen */
+float xClipMinN, xClipMaxN, /* normalized values for
+ clip volume */
+ yClipMinN, yClipMaxN,
+ zClipMinN, zClipMaxN,
+ clipValue; /* mouse input */
+float pzMin, pzMax; /* for a given (theta,phi): calculated in
+ drawViewport(), used in drawFrustrum() */
+
+ /** B/W shades **/
+ /** events from the viewport manager **/
+char propertyName[14];
+char propertyBuffer[256];
+
+ /* global ps variables */
+
+ /** Resource database **/
+XrmDatabase rDB;
+
+ /** variables used for smooth shading **/
+int smoothError = no;
+Pixmap viewmap;
+float Cspec = 0.30;
+float Cdiff = 0.4;
+float Camb = 0.3;
+float coeff = 35.0;
+float saturation = 0.8;
+int smoothHue;
+int smoothConst = 50;
+
+
+
+
+void
+#ifdef _NO_PROTO
+main()
+#else
+main(void)
+#endif
+{
+
+ XGCValues controlGCVals;
+ int i, code;
+
+ char property[256];
+ char *prop = &property[0];
+ char *str_type[20];
+ XrmValue value;
+
+ Atom wm_delete_window;
+ XColor foreColor, backColor;
+ XSizeHints titleSizeHints;
+ Window viewTitleWindow, viewGraphWindow;
+ XSetWindowAttributes viewAttrib;
+ Pixmap spadbits,spadmask;
+
+ /**** Global inits ****/
+ splitPoints = NIL(viewTriple);
+
+ /**** Set up display ****/
+ if ((dsply = XOpenDisplay(getenv("DISPLAY"))) == NULL)
+ {fprintf(stderr,"Could not open display.\n");exit (-1);}
+ scrn = DefaultScreen(dsply);
+ rtWindow = RootWindow(dsply,scrn);
+
+ /**** link Xwindows to viewports - X10 feature ****/
+ table = XCreateAssocTable(nbuckets);
+
+ /**** Create AXIOM color map ****/
+ totalShades = 0;
+ totalColors = XInitSpadFill(dsply,scrn,&colorMap,
+ &totalHues,&totalSolidShades,
+ &totalDitheredAndSolids,&totalShades);
+ if (totalColors < 0) {
+ fprintf(stderr,"ERROR: Could not allocate all the necessary colors.\n");
+ exitWithAck(RootWindow(dsply,scrn),Window,-1);
+ }
+
+
+
+ PSGlobalInit();
+ /* must initiate before using any G/PS functions */
+ /* need character name: used as postscript GC variable */
+ /* need to create ps GCs for all GCs used by drawing in viewWindow */
+
+ /* globalGC1 */
+ controlGCVals.foreground = monoColor(axesColor);
+ controlGCVals.background = backgroundColor;
+ globalGC1 = XCreateGC(dsply,rtWindow,GCForeground |
+ GCBackground ,&controlGCVals);
+ carefullySetFont(globalGC1,globalFont);
+ PSCreateContext(globalGC1, "globalGC1", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* controlMessageGC */
+ controlGCVals.foreground = controlMessageColor;
+ controlGCVals.background = backgroundColor;
+ controlMessageGC = XCreateGC(dsply,rtWindow,GCForeground |
+ GCBackground ,&controlGCVals);
+ carefullySetFont(controlMessageGC,globalFont);
+
+ /* globalGC2 */
+ controlGCVals.foreground = monoColor(labelColor);
+ globalGC2 = XCreateGC(dsply,rtWindow,GCForeground,&controlGCVals);
+ carefullySetFont(globalGC2,buttonFont);
+ PSCreateContext(globalGC2, "globalGC2", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* trashGC */
+ controlGCVals.function = GXcopy;
+ trashGC = XCreateGC(dsply,rtWindow,0 ,&controlGCVals);
+ carefullySetFont(trashGC,buttonFont);
+ PSCreateContext(trashGC, "trashGC", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* componentGC */
+ componentGC = XCreateGC(dsply,rtWindow,0 ,&controlGCVals);
+ carefullySetFont(componentGC,buttonFont);
+ PSCreateContext(componentGC, "componentGC", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* opaqueGC */
+ opaqueGC = XCreateGC(dsply,rtWindow,0 ,&controlGCVals);
+ carefullySetFont(opaqueGC,buttonFont);
+ PSCreateContext(opaqueGC, "opaqueGC", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* renderGC */
+ renderGC = XCreateGC(dsply,rtWindow,0,&controlGCVals);
+ carefullySetFont(renderGC,buttonFont);
+ PSCreateContext(renderGC, "renderGC", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* globGC */
+ globGC = XCreateGC(dsply,rtWindow,0,&controlGCVals);
+ carefullySetFont(globGC,headerFont);
+ PSCreateContext(globGC, "globGC", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* anotherGC */
+ controlGCVals.line_width = colorWidth;
+ anotherGC = XCreateGC(dsply,rtWindow,GCBackground | GCLineWidth |
+ GCFunction ,&controlGCVals);
+ carefullySetFont(anotherGC,titleFont);
+ PSCreateContext(anotherGC, "anotherGC", psNormalWidth, psButtCap,
+ psMiterJoin, psWhite, psBlack);
+
+ /* also create one for rendering (grayscale only for now) */
+ /* assign arbitrary number to renderGC as 9991 - see header.h */
+ PSCreateContext(GC9991, "renderGC", psNormalWidth, psButtCap,
+ psRoundJoin, psWhite, psBlack );
+
+
+ /* processGC */
+ gcVals.background = backgroundColor;
+ processGC = XCreateGC(dsply,rtWindow,GCBackground |
+ GCFillStyle,&gcVals);
+ carefullySetFont(processGC,buttonFont);
+
+ /* lightingGC */
+ controlGCVals.foreground = monoColor(axesColor);
+ controlGCVals.background = backgroundColor;
+ lightingGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
+ ,&controlGCVals);
+ carefullySetFont(lightingGC,lightingFont);
+
+
+ /* volumeGC */
+ volumeGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
+ ,&controlGCVals);
+ carefullySetFont(volumeGC,volumeFont);
+
+ /* quitGC */
+ quitGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
+ ,&controlGCVals);
+ carefullySetFont(quitGC,buttonFont);
+
+ /* saveGC */
+ saveGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
+ ,&controlGCVals);
+ carefullySetFont(saveGC,buttonFont);
+
+
+ /* graphGC */
+ graphGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
+ ,&controlGCVals);
+ carefullySetFont(graphGC,buttonFont);
+ if (!(viewport = (viewPoints *)saymem("viewport3D.c",
+ 1,sizeof(viewPoints)))) {
+ fprintf(stderr,"Ran out of memory trying to create a viewport.\n");
+ exitWithAck(RootWindow(dsply,scrn),Window,-1);
+ }
+ /* Definition of the 4x4 identity matrix. */
+ I[0][0] = 1.0; I[0][1] = 0.0; I[0][2] = 0.0; I[0][3] = 0.0;
+ I[1][0] = 0.0; I[1][1] = 1.0; I[1][2] = 0.0; I[1][3] = 0.0;
+ I[2][0] = 0.0; I[2][1] = 0.0; I[2][2] = 1.0; I[2][3] = 0.0;
+ I[3][0] = 0.0; I[3][1] = 0.0; I[3][2] = 0.0; I[3][3] = 1.0;
+
+ viewport->viewportKey = viewportKeyNum++;
+ viewport->nextViewport = 0;
+ viewport->prevViewport = 0;
+ viewport->deltaX = viewport->deltaX0 = viewData.deltaX;
+ viewport->deltaY = viewport->deltaY0 = viewData.deltaY;
+ viewport->deltaZ = viewport->deltaZ0 = viewData.deltaZ;
+ viewport->scale = viewport->scale0 = viewData.scale;
+ viewport->scaleX = viewData.scaleX;
+ viewport->scaleY = viewData.scaleY;
+ viewport->scaleZ = viewData.scaleZ;
+ viewport->transX = (viewData.xmax + viewData.xmin)/2.0;
+ viewport->transY = (viewData.ymax + viewData.ymin)/2.0;
+ viewport->transZ = (viewData.zmax + viewData.zmin)/2.0;
+
+ viewport->theta = viewport->axestheta = viewport->theta0 = viewData.theta;
+ viewport->phi = viewport->axesphi = viewport->phi0 = viewData.phi;
+ viewport->thetaObj = 0.0;
+ viewport->phiObj = 0.0;
+
+ viewData.title = "untitled";
+ strcpy(viewport->title,viewData.title);
+
+ viewport->axesOn = yes;
+ viewport->regionOn = no;
+ viewport->monoOn = no;
+ viewport->zoomXOn = yes;
+ viewport->zoomYOn = yes;
+ viewport->zoomZOn = yes;
+
+ viewport->originrOn = yes;
+ viewport->objectrOn = no;
+ viewport->originFlag = no;
+
+ viewport->xyOn = no;
+ viewport->xzOn = no;
+ viewport->yzOn = no;
+
+ viewport->closing = no;
+ viewport->allowDraw = yes; /*if no, just draw axes the first time */
+ viewport->needNorm = yes;
+
+ viewport->lightVector[0] = -0.5;
+ viewport->lightVector[1] = 0.5;
+ viewport->lightVector[2] = 0.5;
+ viewport->translucency = viewData.translucency;
+
+ viewport->hueOffset = viewData.hueOff;
+ viewport->numberOfHues = viewData.numOfHues;
+ viewport->hueTop = viewData.hueOff + viewData.numOfHues;
+ if (viewport->hueTop > totalHues-1) viewport->hueTop = totalHues-1;
+ viewport->diagonals = viewData.diagonals;
+
+ /* make theta in [0..2pi) and phi in (-pi..pi] */
+ while (viewport->theta >= two_pi) {
+ viewport->theta -= two_pi;
+ }
+ while (viewport->theta < 0.0) {
+ viewport->theta += two_pi;
+ }
+ while (viewport->phi > pi) {
+ viewport->phi -= two_pi;
+ }
+ while (viewport->phi <= -pi) {
+ viewport->phi += two_pi;
+ }
+
+ while (viewport->axestheta >= two_pi) {
+ viewport->axestheta -= two_pi;
+ }
+ while (viewport->axestheta < 0.0) {
+ viewport->axestheta += two_pi;
+ }
+ while (viewport->axesphi > pi) {
+ viewport->axesphi -= two_pi;
+ }
+ while (viewport->axesphi <= -pi) {
+ viewport->axesphi += two_pi;
+ }
+
+ /* Initialize the rotation matrix about the origin. */
+ sinTheta = sin(-viewport->theta);
+ cosTheta = cos(-viewport->theta);
+ sinPhi = sin(viewport->phi);
+ cosPhi = cos(viewport->phi);
+ ROTATE(R); /* angles theta and phi are global */
+
+ /* Initialize the rotation matrix about the object's center of volume. */
+ sinTheta = sin(-viewport->thetaObj);
+ cosTheta = cos(-viewport->thetaObj);
+ sinPhi = sin(viewport->phiObj);
+ cosPhi = cos(viewport->phiObj);
+ ROTATE1(R1); /* angles theta and phi are global */
+
+
+ /* Initialize the non-uniform scaling matrix. */
+ SCALE(viewport->scaleX,viewport->scaleY,viewport->scaleZ,S);
+ /* Initialize the translation matrix. */
+ TRANSLATE(-viewport->deltaX,-viewport->deltaY,0.0,T);
+ /**** make the windows for the viewport ****/
+ spadbits = XCreateBitmapFromData(dsply,rtWindow,
+ spadBitmap_bits,
+ spadBitmap_width,spadBitmap_height);
+ spadmask = XCreateBitmapFromData(dsply,rtWindow,
+ spadMask_bits,
+ spadMask_width,spadMask_height);
+ viewAttrib.background_pixel = backgroundColor;
+ viewAttrib.border_pixel = foregroundColor;
+
+ viewAttrib.override_redirect = overrideManager;
+
+ viewAttrib.colormap = colorMap;
+ foreColor.pixel = foregroundColor;
+ backColor.pixel = backgroundColor;
+/*
+ foreColor.pixel = viewCursorForeground;
+ backColor.pixel = viewCursorBackground;
+*/
+ XQueryColor(dsply,colorMap,&foreColor);
+ XQueryColor(dsply,colorMap,&backColor);
+ viewAttrib.cursor = XCreatePixmapCursor(dsply,spadbits,spadmask,
+ &foreColor,&backColor,spadBitmap_x_hot,spadBitmap_y_hot);
+ viewAttrib.event_mask = titleMASK;
+ if (viewData.vW) {
+ titleSizeHints.flags = PPosition | PSize;
+ titleSizeHints.x = viewData.vX;
+ titleSizeHints.y = viewData.vY;
+ titleSizeHints.width = viewData.vW;
+ titleSizeHints.height = viewData.vH;
+ } else { /* ain't gonna allow this for now... */
+ titleSizeHints.flags = PSize;
+ titleSizeHints.width = viewWidth;
+ titleSizeHints.height = viewHeight;
+ }
+
+ viewTitleWindow = XCreateWindow(dsply,rtWindow,viewData.vX,viewData.vY,
+ viewData.vW,viewData.vH,viewBorderWidth+3,
+ CopyFromParent,InputOutput,CopyFromParent,
+ viewportTitleCreateMASK,&viewAttrib);
+
+ wm_delete_window = XInternAtom(dsply, "WM_DELETE_WINDOW", False);
+ (void) XSetWMProtocols(dsply, viewTitleWindow, &wm_delete_window, 1);
+
+ XSetNormalHints(dsply,viewTitleWindow,&titleSizeHints);
+ if (strlen(viewport->title) < 30)
+ XSetStandardProperties(dsply,viewTitleWindow,"AXIOM 3D",viewport->title,
+ None,NULL,0,&titleSizeHints);
+ else
+ XSetStandardProperties(dsply,viewTitleWindow,"AXIOM 3D","3D AXIOM Graph",
+ None,NULL,0,&titleSizeHints);
+ viewport->titleWindow = viewTitleWindow;
+
+ viewAttrib.event_mask = viewportMASK;
+ viewSizeHints.flags = PPosition | PSize;
+ viewSizeHints.x = -(viewBorderWidth+3);
+ viewSizeHints.y = titleHeight;
+ viewSizeHints.width = titleSizeHints.width;
+ viewSizeHints.height = titleSizeHints.height-(titleHeight+appendixHeight);
+ viewGraphWindow = XCreateWindow(dsply,viewTitleWindow,
+ viewSizeHints.x,viewSizeHints.y,
+ viewSizeHints.width,viewSizeHints.height,
+ viewBorderWidth+3,
+ CopyFromParent,InputOutput,CopyFromParent,
+ viewportCreateMASK,&viewAttrib);
+ XSetNormalHints(dsply,viewGraphWindow,&viewSizeHints);
+ XSetStandardProperties(dsply,viewGraphWindow,"","",None,NULL,0,
+ &viewSizeHints);
+ viewport->viewWindow = viewGraphWindow;
+ graphWindowAttrib.width = viewSizeHints.width;
+ graphWindowAttrib.height = viewSizeHints.height;
+
+ if (viewport->hueOffset != viewport->hueTop) {
+ multiColorFlag = yes;
+ redoColor = no;
+ } else {
+ if (viewport->hueTop < 11)
+ smoothHue = viewport->hueTop*6;
+ else {
+ if (viewport->hueTop > 10 && viewport->hueTop < 16)
+ smoothHue = viewport->hueTop*20 - 140;
+ else smoothHue = viewport->hueTop*12 - 12;
+ }
+ redoColor = yes;
+ }
+
+
+} /* main() */
+
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/transform3d.c.pamphlet b/src/graph/view3D/transform3d.c.pamphlet
new file mode 100644
index 00000000..77da7555
--- /dev/null
+++ b/src/graph/view3D/transform3d.c.pamphlet
@@ -0,0 +1,179 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D transform3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _TRANSFORM3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+
+#include "header.h"
+
+#include "all_3d.H1"
+
+void
+#ifdef _NO_PROTO
+matrixMultiply4x4(xxA,xxB,array)
+ float xxA[4][4], xxB[4][4], array[4][4];
+#else
+matrixMultiply4x4(float xxA[4][4],float xxB[4][4],float array[4][4])
+#endif
+{
+ array[0][0] = xxA[0][0]*xxB[0][0] + xxA[0][1]*xxB[1][0] +
+ xxA[0][2]*xxB[2][0] + xxA[0][3]*xxB[3][0];
+ array[1][0] = xxA[1][0]*xxB[0][0] + xxA[1][1]*xxB[1][0] +
+ xxA[1][2]*xxB[2][0] + xxA[1][3]*xxB[3][0];
+ array[2][0] = xxA[2][0]*xxB[0][0] + xxA[2][1]*xxB[1][0] +
+ xxA[2][2]*xxB[2][0] + xxA[2][3]*xxB[3][0];
+ array[3][0] = xxA[3][0]*xxB[0][0] + xxA[3][1]*xxB[1][0] +
+ xxA[3][2]*xxB[2][0] + xxA[3][3]*xxB[3][0];
+ array[0][1] = xxA[0][0]*xxB[0][1] + xxA[0][1]*xxB[1][1] +
+ xxA[0][2]*xxB[2][1] + xxA[0][3]*xxB[3][1];
+ array[1][1] = xxA[1][0]*xxB[0][1] + xxA[1][1]*xxB[1][1] +
+ xxA[1][2]*xxB[2][1] + xxA[1][3]*xxB[3][1];
+ array[2][1] = xxA[2][0]*xxB[0][1] + xxA[2][1]*xxB[1][1] +
+ xxA[2][2]*xxB[2][1] + xxA[2][3]*xxB[3][1];
+ array[3][1] = xxA[3][0]*xxB[0][1] + xxA[3][1]*xxB[1][1] +
+ xxA[3][2]*xxB[2][1] + xxA[3][3]*xxB[3][1];
+ array[0][2] = xxA[0][0]*xxB[0][2] + xxA[0][1]*xxB[1][2] +
+ xxA[0][2]*xxB[2][2] + xxA[0][3]*xxB[3][2];
+ array[1][2] = xxA[1][0]*xxB[0][2] + xxA[1][1]*xxB[1][2] +
+ xxA[1][2]*xxB[2][2] + xxA[1][3]*xxB[3][2];
+ array[2][2] = xxA[2][0]*xxB[0][2] + xxA[2][1]*xxB[1][2] +
+ xxA[2][2]*xxB[2][2] + xxA[2][3]*xxB[3][2];
+ array[3][2] = xxA[3][0]*xxB[0][2] + xxA[3][1]*xxB[1][2] +
+ xxA[3][2]*xxB[2][2] + xxA[3][3]*xxB[3][2];
+ array[0][3] = xxA[0][0]*xxB[0][3] + xxA[0][1]*xxB[1][3] +
+ xxA[0][2]*xxB[2][3] + xxA[0][3]*xxB[3][3];
+ array[1][3] = xxA[1][0]*xxB[0][3] + xxA[1][1]*xxB[1][3] +
+ xxA[1][2]*xxB[2][3] + xxA[1][3]*xxB[3][3];
+ array[2][3] = xxA[2][0]*xxB[0][3] + xxA[2][1]*xxB[1][3] +
+ xxA[2][2]*xxB[2][3] + xxA[2][3]*xxB[3][3];
+ array[3][3] = xxA[3][0]*xxB[0][3] + xxA[3][1]*xxB[1][3] +
+ xxA[3][2]*xxB[2][3] + xxA[3][3]*xxB[3][3];
+}
+
+
+void
+#ifdef _NO_PROTO
+vectorMatrix4(xxD,xxE,xxF)
+ float xxD[4], xxE[4][4], xxF[4];
+#else
+vectorMatrix4(float xxD[4],float xxE[4][4],float xxF[4])
+#endif
+{
+ xxF[0]= xxD[0]*xxE[0][0] + xxD[1]*xxE[1][0] + xxD[2]*xxE[2][0] + xxD[3]*xxE[3][0];
+ xxF[1]= xxD[0]*xxE[0][1] + xxD[1]*xxE[1][1] + xxD[2]*xxE[2][1] + xxD[3]*xxE[3][1];
+ xxF[2]= xxD[0]*xxE[0][2] + xxD[1]*xxE[1][2] + xxD[2]*xxE[2][2] + xxD[3]*xxE[3][2];
+ xxF[3]= xxD[0]*xxE[0][3] + xxD[1]*xxE[1][3] + xxD[2]*xxE[2][3] + xxD[3]*xxE[3][3];
+}
+
+
+void
+#ifdef _NO_PROTO
+ROTATE(xxR)
+ float xxR[4][4];
+#else
+ROTATE(float xxR[4][4])
+#endif
+{
+ xxR[0][0]= -(cosTheta); xxR[0][1]= -(-sinTheta*cosPhi); xxR[0][2]= -(sinTheta*sinPhi); xxR[0][3]= 0.0;
+ xxR[1][0]= -(sinTheta); xxR[1][1]= -(cosTheta*cosPhi); xxR[1][2]= -(-cosTheta*sinPhi); xxR[1][3]= 0.0;
+ xxR[2][0]= 0.0; xxR[2][1]= -(sinPhi); xxR[2][2]= -(cosPhi); xxR[2][3]= 0.0;
+ xxR[3][0]= 0.0; xxR[3][1]= 0.0; xxR[3][2]= 0.0; xxR[3][3]= -(1.0);
+}
+
+void
+#ifdef _NO_PROTO
+ROTATE1(xxR)
+ float xxR[4][4];
+#else
+ROTATE1(float xxR[4][4])
+#endif
+{
+ xxR[0][0]= (cosTheta); xxR[0][1]= (-sinTheta*cosPhi); xxR[0][2]= (sinTheta*sinPhi); xxR[0][3]= 0.0;
+ xxR[1][0]= (sinTheta); xxR[1][1]= (cosTheta*cosPhi); xxR[1][2]= (-cosTheta*sinPhi); xxR[1][3]= 0.0;
+ xxR[2][0]= 0.0; xxR[2][1]= (sinPhi); xxR[2][2]= (cosPhi); xxR[2][3]= 0.0;
+ xxR[3][0]= 0.0; xxR[3][1]= 0.0; xxR[3][2]= 0.0; xxR[3][3]= (1.0);
+}
+
+
+void
+#ifdef _NO_PROTO
+SCALE(x,y,z,xxS)
+ float x, y, z, xxS[4][4];
+#else
+SCALE(float x,float y,float z,float xxS[4][4])
+#endif
+{
+ xxS[0][0] = x; xxS[0][1] = 0.0; xxS[0][2] = 0.0; xxS[0][3] = 0.0;
+ xxS[1][0] = 0.0; xxS[1][1] = y; xxS[1][2] = 0.0; xxS[1][3] = 0.0;
+ xxS[2][0] = 0.0; xxS[2][1] = 0.0; xxS[2][2] = z; xxS[2][3] = 0.0;
+ xxS[3][0] = 0.0; xxS[3][1] = 0.0; xxS[3][2] = 0.0; xxS[3][3] = 1.0;
+}
+
+
+void
+#ifdef _NO_PROTO
+TRANSLATE(x,y,z,xxT)
+ float x, y, z, xxT[4][4];
+#else
+TRANSLATE(float x,float y,float z,float xxT[4][4])
+#endif
+{
+ xxT[0][0] = 1.0; xxT[0][1] = 0.0; xxT[0][2] = 0.0; xxT[0][3] = 0.0;
+ xxT[1][0] = 0.0; xxT[1][1] = 1.0; xxT[1][2] = 0.0; xxT[1][3] = 0.0;
+ xxT[2][0] = 0.0; xxT[2][1] = 0.0; xxT[2][2] = -1.0; xxT[2][3] = 0.0;
+ xxT[3][0] = x; xxT[3][1] = y; xxT[3][2] = z; xxT[3][3] = 1.0;
+}
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/viewport3d.c.pamphlet b/src/graph/view3D/viewport3d.c.pamphlet
new file mode 100644
index 00000000..cb69dd3c
--- /dev/null
+++ b/src/graph/view3D/viewport3d.c.pamphlet
@@ -0,0 +1,941 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D viewport3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _VIEWPORT3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "spadBitmap.bitmap"
+#include "spadMask.mask"
+
+#include "header.h"
+ /*** definition for the axes and labels - this is the minimun that will be
+ drawn on the window - thus allowing the user some idea of the
+ orientation of the coordinate axes when rotating, etc. The
+ drawing of the mesh is aborted when an appropriate X event occurs.
+ The mesh should be scaled to the range of [-100..100] in all
+ directions. axisRange defines the range...change the stuff below
+ if that has changed. ***/
+#include "static.h"
+#include "draw.h"
+#include "volume.h"
+#include "mode.h"
+
+#include "util.H1"
+#include "Gfun.H1"
+#include "XSpadFill.H1"
+#include "all_3d.H1"
+
+#define axesOffset 5
+
+Atom wm_delete_window;
+
+
+/***************************
+ *** void writeTitle() ***
+ ***************************/
+
+void
+#ifdef _NO_PROTO
+writeTitle ()
+#else
+writeTitle (void)
+#endif
+{
+
+ int strlength;
+ XWindowAttributes twInfo;
+
+ XGetWindowAttributes(dsply, viewport->titleWindow, &twInfo);
+ if (mono || viewport->monoOn)
+ GSetForeground(anotherGC, (float)foregroundColor, Xoption);
+ else
+ GSetForeground(anotherGC, (float)titleColor, Xoption);
+ XClearWindow(dsply, viewport->titleWindow);
+
+ strlength = strlen(viewport->title);
+ GDrawImageString(anotherGC, viewport->titleWindow,
+ centerX(anotherGC, viewport->title, strlength,
+ twInfo.width), 15,
+ viewport->title, strlength, Xoption);
+
+}
+
+
+/****************************
+ * void drawPreViewport() *
+ * *
+ * draws the axes and boxes *
+ * before the actual stuff. *
+ * all incoming signals *
+ * should be block and no *
+ * check for pending X *
+ * events are made. *
+ * *
+ ****************************/
+
+void
+#ifdef _NO_PROTO
+drawPreViewport (dFlag)
+ int dFlag; /* display flag: PS, X, etc. */
+#else
+drawPreViewport (int dFlag)
+#endif
+{
+
+ int i, j, vPx0, vPy0, vPx1, vPy1;
+ /* for drawing the box */
+ float vPz, absTransX, absTransY;
+ XPoint blackbox[3], line[2];
+ RGB axes_rgb, clipbox_rgb, boundbox_rgb;
+
+ axes_rgb.r = 0.8; axes_rgb.g = 0.6; axes_rgb.b = 0.2;
+ clipbox_rgb.r = 0.4; clipbox_rgb.g = 0.5; clipbox_rgb.b = 0.9;
+ boundbox_rgb.r = 0.4; boundbox_rgb.g = 0.7; boundbox_rgb.b = 0.9;
+
+ XGetWindowAttributes(dsply, viewport->viewWindow, &vwInfo);
+ graphWindowAttrib = vwInfo;
+
+ /* Calculate various factors for use in projection */
+ /* Scale so that plot the scaling between the axes remains constant
+ and fits within the smaller of the two dimensions. */
+
+ xCenter = vwInfo.width / 2;
+ yCenter = vwInfo.height / 2;
+
+ if (vwInfo.height <= vwInfo.width) {
+ viewScale = viewport->scale * vwInfo.height / viewHeight;
+ }
+ else {
+ viewScale = viewport->scale * vwInfo.width / viewWidth;
+ }
+
+ /* Draw the projected image */
+ /** draw the axes without heeding to X interrupts, first **/
+
+ if (dFlag == Xoption) /* do this for X option only */
+ XClearWindow(dsply, viewport->viewWindow);
+
+ sinTheta = sin(-viewport->axestheta);
+ cosTheta = cos(-viewport->axestheta);
+ sinPhi = sin(viewport->axesphi);
+ cosPhi = cos(viewport->axesphi);
+
+ /* Create transformation matrices */
+ ROTATE(R); /* angles theta and phi are global */
+ SCALE(viewport->scaleX,viewport->scaleY,viewport->scaleZ,S);
+ TRANSLATE(-viewport->deltaX,-viewport->deltaY,0.0,T);
+
+ /**** Pre Draw Routine ****/
+
+ if ((dFlag == PSoption) && (foregroundColor == white)) {
+ GSetForeground(globGC,(float)backgroundColor,dFlag);
+ blackbox[0].x = vwInfo.width; blackbox[0].y = vwInfo.height;
+ blackbox[1].x = 0; blackbox[1].y = 0;
+ blackbox[2].x = 0; blackbox[2].y = vwInfo.height;
+ if (viewport->monoOn || mono) {
+ PSFillPolygon(globGC, blackbox, 3);
+ } else {
+ PSColorPolygon(0.0,0.0,0.0,blackbox,4);
+ }
+ blackbox[0].x = vwInfo.width; blackbox[0].y = 0;
+ blackbox[1].x = 0; blackbox[1].y = 0;
+ blackbox[2].x = vwInfo.width; blackbox[2].y = vwInfo.height;
+ if (viewport->monoOn || mono) {
+ PSFillPolygon(globGC, blackbox, 3);
+ } else {
+ PSColorPolygon(0.0,0.0,0.0,blackbox,4);
+ }
+ }
+
+ /* axes */
+
+ for (i=0; i < 3; i++) {
+ projectStuff(axes[i][0],axes[i][1],axes[i][2],&vPx0,&vPy0,&vPz);
+ axesXY[i][0] = vPx0; axesXY[i][1] = vPy0; axesZ[i][0] = vPz;
+ projectStuff(axes[i][3],axes[i][4],axes[i][5],&vPx1,&vPy1,&vPz);
+ axesXY[i][2] = vPx1; axesXY[i][3] = vPy1; axesZ[i][1] = vPz;
+ if (viewport->axesOn) {
+ if (viewport->monoOn || mono) {
+ GSetForeground(globalGC1,(float)foregroundColor,dFlag);
+ GSetForeground(globGC,(float)foregroundColor,dFlag);
+ GDrawLine(globalGC1,viewport->viewWindow,vPx0,vPy0,vPx1,vPy1,dFlag);
+ } else {
+ if (dFlag == PSoption) {
+ GSetForeground(globGC,(float)foregroundColor,dFlag);
+ line[0].x = vPx0; line[0].y = vPy0;
+ line[1].x = vPx1; line[1].y = vPy1;
+ PSDrawColor(axes_rgb.r,axes_rgb.g,axes_rgb.b,line,2);
+ } else {
+ GSetForeground(globalGC1,(float)monoColor(axesColor),dFlag);
+ GSetForeground(globGC,(float)monoColor(labelColor),dFlag);
+ GDrawLine(globalGC1,viewport->viewWindow,vPx0,vPy0,vPx1,vPy1,dFlag);
+ }
+ }
+ if (i == 0) {
+ if (axesXY[0][2] < axesXY[0][0]) vPx1 -= axesOffset;
+ else vPx1 += axesOffset;
+ if (axesXY[0][3] < axesXY[0][1]) vPy1 -= axesOffset;
+ else vPy1 += axesOffset;
+ if (!viewport->yzOn)
+ GDrawString(globGC,viewport->viewWindow,vPx1,vPy1,"X",1,dFlag);
+ } else {
+ if (i == 1) {
+ if (axesXY[1][2] < axesXY[1][0]) vPx1 -= axesOffset;
+ else vPx1 += axesOffset;
+ if (axesXY[1][3] < axesXY[1][1]) vPy1 -= axesOffset;
+ else vPy1 += axesOffset;
+ if (!viewport->xzOn)
+ GDrawString(globGC,viewport->viewWindow,vPx1,vPy1,"Y",1,dFlag);
+ } else {
+ if (axesXY[2][2] < axesXY[2][0]) vPx1 -= axesOffset;
+ else vPx1 += axesOffset;
+ if (axesXY[2][3] < axesXY[2][1]) vPy1 -= axesOffset;
+ else vPy1 += axesOffset;
+ if (!viewport->xyOn)
+ GDrawString(globGC,viewport->viewWindow,vPx1,vPy1,"Z",1,dFlag);
+ }
+ }
+ GSetForeground(globalGC1,(float)monoColor(buttonColor),dFlag);
+ GSetForeground(globGC,(float)monoColor(buttonColor),dFlag);
+ } /* if viewport->axesOn */
+ }
+
+ viewport->transX = (viewData.xmax + viewData.xmin)/2.0;
+ viewport->transY = (viewData.ymax + viewData.ymin)/2.0;
+ viewport->transZ = (viewData.zmax + viewData.zmin)/2.0;
+
+ absTransX = absolute(viewport->transX);
+ absTransY = absolute(viewport->transY);
+ if ((absTransX > 0.5) || (absTransY > 0.5)) {
+ if (absTransX > absTransY)
+ reScale = 50.0 * absTransX / viewData.scaleToView;
+ else
+ reScale = 50.0 * absTransY / viewData.scaleToView;
+ if (reScale < 100.0) reScale = 100.0;
+ } else {
+ reScale = 100.0;
+ }
+
+ sinTheta = sin(-viewport->thetaObj);
+ cosTheta = cos(-viewport->thetaObj);
+ sinPhi = sin(viewport->phiObj);
+ cosPhi = cos(viewport->phiObj);
+ ROTATE1(R1);
+
+ if (viewport->originFlag) viewport->originFlag = no;
+ sinTheta = sin(-viewport->axestheta);
+ cosTheta = cos(-viewport->axestheta);
+ sinPhi = sin(viewport->axesphi);
+ cosPhi = cos(viewport->axesphi);
+ ROTATE(R);
+
+ /* region box */
+ if (viewData.clipbox) {
+ clipCorners[0].x = viewData.clipXmin;
+ clipCorners[0].y = viewData.clipYmin;
+ clipCorners[0].z = viewData.clipZmin;
+ clipCorners[1].x = viewData.clipXmax;
+ clipCorners[1].y = viewData.clipYmin;
+ clipCorners[1].z = viewData.clipZmin;
+ clipCorners[2].x = viewData.clipXmax;
+ clipCorners[2].y = viewData.clipYmin;
+ clipCorners[2].z = viewData.clipZmax;
+ clipCorners[3].x = viewData.clipXmin;
+ clipCorners[3].y = viewData.clipYmin;
+ clipCorners[3].z = viewData.clipZmax;
+ clipCorners[4].x = viewData.clipXmin;
+ clipCorners[4].y = viewData.clipYmax;
+ clipCorners[4].z = viewData.clipZmin;
+ clipCorners[5].x = viewData.clipXmax;
+ clipCorners[5].y = viewData.clipYmax;
+ clipCorners[5].z = viewData.clipZmin;
+ clipCorners[6].x = viewData.clipXmax;
+ clipCorners[6].y = viewData.clipYmax;
+ clipCorners[6].z = viewData.clipZmax;
+ clipCorners[7].x = viewData.clipXmin;
+ clipCorners[7].y = viewData.clipYmax;
+ clipCorners[7].z = viewData.clipZmax;
+
+ GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,dFlag);
+
+ /* project the 8 corners of the box */
+ for (i=0;i<8;i++) projectAPoint(&(clipCorners[i]));
+
+ for (i=0;i<6;i++) {
+ clipBox[i].inside = ((clipBox[i].pointsPtr[2]->px -
+ clipBox[i].pointsPtr[1]->px) *
+ (clipBox[i].pointsPtr[1]->py -
+ clipBox[i].pointsPtr[0]->py) -
+ (clipBox[i].pointsPtr[2]->py -
+ clipBox[i].pointsPtr[1]->py) *
+ (clipBox[i].pointsPtr[1]->px -
+ clipBox[i].pointsPtr[0]->px)) < 0;
+ if (clipBox[i].inside) {
+ for (j=0; j<3; j++) {
+ quadMesh[j].x = clipBox[i].pointsPtr[j]->px;
+ quadMesh[j].y = clipBox[i].pointsPtr[j]->py;
+ }
+ if (viewport->monoOn || mono) {
+ GSetForeground(trashGC,(float)foregroundColor,dFlag);
+ GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
+ CoordModeOrigin, dFlag);
+ } else {
+ if (dFlag == PSoption) {
+ GSetForeground(trashGC,(float)clipBoxInline, dFlag);
+ line[0].x = quadMesh[0].x; line[0].y = quadMesh[0].y;
+ line[1].x = quadMesh[1].x; line[1].y = quadMesh[1].y;
+ PSDrawColor(clipbox_rgb.r,clipbox_rgb.g,clipbox_rgb.b,line,2);
+ line[0].x = quadMesh[1].x; line[0].y = quadMesh[1].y;
+ line[1].x = quadMesh[2].x; line[1].y = quadMesh[2].y;
+ PSDrawColor(clipbox_rgb.r,clipbox_rgb.g,clipbox_rgb.b,line,2);
+ } else {
+ GSetForeground(trashGC,(float)clipBoxInline, dFlag);
+ GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
+ CoordModeOrigin, dFlag);
+ }
+ }
+ }
+ }
+ } /* if viewData.clipbox */
+
+ /* VOLUME panel stuff */
+ if ((doingPanel == VOLUMEpanel) || viewData.box) {
+
+ GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,dFlag);
+
+ for (i=0;i<8;i++) {
+ /* project the 8 corners of the box */
+ projectAPoint(&(corners[i]));
+ if (i) {
+ if (corners[i].pz > pzMax) pzMax = corners[i].pz;
+ else if (corners[i].pz < pzMin) pzMin = corners[i].pz;
+ } else
+ pzMax = pzMin = corners[i].pz;
+ }
+
+ for (i=0;i<6;i++) {
+ /* Process the 6 sides of the boxes.
+ Here, we calculate, for each side (defined by two segments)
+ whether it is facing towards or away from the viewer. if
+ facing, away, we draw them first. later we draw the ones
+ facing the viewer. (this is a sort of backface removal
+ scheme. */
+ /* We define the normal vector for the box as vA X vB where
+ vA=p2-p0 and vB=p1-p0. All we really care about, though,
+ is what sign the normal is (whether it is towards or away
+ from the viewer - so we just take the triple product of
+ it against the eye vector, which is, conveniently enough,
+ simply [0 0 1]. Hence, only the Z component of the
+ cross product is calculated. (Actually, we are using the
+ projected normal - that's how we are able to use the
+ trick of just taking the Z component. */
+ box[i].inside = ((box[i].pointsPtr[2]->px -
+ box[i].pointsPtr[0]->px) * /* Ax * */
+ (box[i].pointsPtr[1]->py -
+ box[i].pointsPtr[0]->py) - /* By - */
+ (box[i].pointsPtr[2]->py -
+ box[i].pointsPtr[0]->py) * /* Ay * */
+ (box[i].pointsPtr[1]->px -
+ box[i].pointsPtr[0]->px)) /* Bx */
+ < 0;
+ if (box[i].inside) {
+ for (j=0; j<3; j++) {
+ quadMesh[j].x = box[i].pointsPtr[j]->px;
+ quadMesh[j].y = box[i].pointsPtr[j]->py;
+ }
+ if (viewport->monoOn || mono) {
+ GSetForeground(trashGC,(float)foregroundColor,dFlag);
+ GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
+ CoordModeOrigin, dFlag);
+ } else {
+ if (dFlag == PSoption) {
+ GSetForeground(trashGC,(float)boxInline, dFlag );
+ line[0].x = quadMesh[0].x; line[0].y = quadMesh[0].y;
+ line[1].x = quadMesh[1].x; line[1].y = quadMesh[1].y;
+ PSDrawColor(boundbox_rgb.r,boundbox_rgb.g,boundbox_rgb.b,line,2);
+ line[0].x = quadMesh[1].x; line[0].y = quadMesh[1].y;
+ line[1].x = quadMesh[2].x; line[1].y = quadMesh[2].y;
+ PSDrawColor(boundbox_rgb.r,boundbox_rgb.g,boundbox_rgb.b,line,2);
+ } else {
+ GSetForeground(trashGC,(float)boxInline, dFlag );
+ GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
+ CoordModeOrigin, dFlag);
+ }
+ }
+ }
+ }
+ } /* if viewData.box */
+
+ /* Write out view data */
+ if (dFlag == Xoption) { /* do this only for X option */
+ writeControlMessage();
+ XFlush(dsply);
+ }
+}
+
+
+/********************************/
+/*** void drawTheViewport() ***/
+/********************************/
+
+void
+#ifdef _NO_PROTO
+drawTheViewport (dFlag)
+ int dFlag; /* display flag: PS, X,... */
+#else
+drawTheViewport (int dFlag)
+#endif
+{
+
+ int i,j;
+ XPoint line[2];
+ RGB clipbox_rgb, boundbox_rgb;
+
+ clipbox_rgb.r = 0.4; clipbox_rgb.g = 0.5; clipbox_rgb.b = 0.9;
+ boundbox_rgb.r = 0.4; boundbox_rgb.g = 0.7; boundbox_rgb.b = 0.9;
+
+ /**** Draw Routine ****/
+
+ if (viewport->allowDraw && (doingPanel != VOLUMEpanel)) {
+ /* Do not draw the mesh stuff if we're in the process of changing
+ the viewing volume; we just want to see the volume */
+
+ /* drawMore allows the drawing to continue if no relevant XEvent occurs */
+ drawMore = yes;
+ drawMore = keepDrawingViewport();
+ draw3DComponents(dFlag);
+
+ } /*if viewport->allowDraw */
+
+ /**** Post Draw Routine ****/
+ if (viewData.clipbox) { /* draw the front 3 lines of region box */
+ GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,dFlag);
+ for (i=0; i<6; i++) {
+ if (!(clipBox[i].inside)) {
+ for (j=0; j<4; j++) {
+ quadMesh[j].x = clipBox[i].pointsPtr[j]->px;
+ quadMesh[j].y = clipBox[i].pointsPtr[j]->py;
+ }
+ if (viewport->monoOn || mono) {
+ GSetForeground(trashGC,(float)foregroundColor,dFlag);
+ GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
+ CoordModeOrigin, dFlag);
+ } else {
+ if (dFlag == PSoption) {
+ GSetForeground(trashGC,(float)boxInline, dFlag );
+ line[0].x = quadMesh[0].x; line[0].y = quadMesh[0].y;
+ line[1].x = quadMesh[1].x; line[1].y = quadMesh[1].y;
+ PSDrawColor(clipbox_rgb.r,clipbox_rgb.g,clipbox_rgb.b,line,2);
+ line[0].x = quadMesh[1].x; line[0].y = quadMesh[1].y;
+ line[1].x = quadMesh[2].x; line[1].y = quadMesh[2].y;
+ PSDrawColor(clipbox_rgb.r,clipbox_rgb.g,clipbox_rgb.b,line,2);
+ } else {
+ GSetForeground(trashGC,(float)boxInline, dFlag );
+ GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
+ CoordModeOrigin, dFlag);
+ }
+ }
+ }
+ }
+ }
+
+ if ((doingPanel==VOLUMEpanel) || viewData.box) {
+ GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,dFlag);
+ for (i=0; i<6; i++) {
+ if (!(box[i].inside)) {
+ for (j=0; j<4; j++) {
+ quadMesh[j].x = box[i].pointsPtr[j]->px;
+ quadMesh[j].y = box[i].pointsPtr[j]->py;
+ }
+ if (viewport->monoOn || mono) {
+ GSetForeground(trashGC,(float)foregroundColor,dFlag);
+ GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
+ CoordModeOrigin, dFlag);
+ } else {
+ if (dFlag == PSoption) {
+ GSetForeground(trashGC,(float)boxInline, dFlag );
+ line[0].x = quadMesh[0].x; line[0].y = quadMesh[0].y;
+ line[1].x = quadMesh[1].x; line[1].y = quadMesh[1].y;
+ PSDrawColor(boundbox_rgb.r,boundbox_rgb.g,boundbox_rgb.b,line,2);
+ line[0].x = quadMesh[1].x; line[0].y = quadMesh[1].y;
+ line[1].x = quadMesh[2].x; line[1].y = quadMesh[2].y;
+ PSDrawColor(boundbox_rgb.r,boundbox_rgb.g,boundbox_rgb.b,line,2);
+ } else {
+ GSetForeground(trashGC,(float)boxInline, dFlag );
+ GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
+ CoordModeOrigin, dFlag);
+ }
+ }
+ }
+ }
+ }
+
+ if (dFlag == Xoption) /* do this for X option only */
+ XFlush(dsply);
+
+ if (smoothError) {
+ strcpy(control->message,"Cannot alloc more smooth shades.");
+ writeControlMessage();
+ smoothError = no;
+ }
+
+} /* drawTheViewport */
+
+/************************************
+ *** viewPoints *makeViewport() ***
+ ************************************/
+
+viewPoints *
+#ifdef _NO_PROTO
+makeViewport ()
+#else
+makeViewport (void)
+#endif
+{
+
+ Pixmap spadbits,spadmask;
+ XSetWindowAttributes viewAttrib;
+ XSizeHints titleSizeHints;
+ Window viewTitleWindow, viewGraphWindow;
+ XColor foreColor, backColor;
+
+ /**** create a viewport ****/
+
+ if (!(viewport = (viewPoints *)saymem("viewport3D.c",
+ 1,sizeof(viewPoints)))) {
+ fprintf(stderr,"Ran out of memory trying to create a viewport.\n");
+ exitWithAck(RootWindow(dsply,scrn),Window,-1);
+ }
+ /* Definition of the 4x4 identity matrix. */
+ I[0][0] = 1.0; I[0][1] = 0.0; I[0][2] = 0.0; I[0][3] = 0.0;
+ I[1][0] = 0.0; I[1][1] = 1.0; I[1][2] = 0.0; I[1][3] = 0.0;
+ I[2][0] = 0.0; I[2][1] = 0.0; I[2][2] = 1.0; I[2][3] = 0.0;
+ I[3][0] = 0.0; I[3][1] = 0.0; I[3][2] = 0.0; I[3][3] = 1.0;
+
+ viewport->viewportKey = viewportKeyNum++;
+ viewport->nextViewport = 0;
+ viewport->prevViewport = 0;
+ viewport->deltaX = viewport->deltaX0 = viewData.deltaX;
+ viewport->deltaY = viewport->deltaY0 = viewData.deltaY;
+ viewport->deltaZ = viewport->deltaZ0 = viewData.deltaZ;
+ viewport->scale = viewport->scale0 = viewData.scale;
+ viewport->scaleX = viewData.scaleX;
+ viewport->scaleY = viewData.scaleY;
+ viewport->scaleZ = viewData.scaleZ;
+ viewport->transX = (viewData.xmax + viewData.xmin)/2.0;
+ viewport->transY = (viewData.ymax + viewData.ymin)/2.0;
+ viewport->transZ = (viewData.zmax + viewData.zmin)/2.0;
+
+ viewport->theta = viewport->axestheta = viewport->theta0 = viewData.theta;
+ viewport->phi = viewport->axesphi = viewport->phi0 = viewData.phi;
+ viewport->thetaObj = 0.0;
+ viewport->phiObj = 0.0;
+
+ strcpy(viewport->title,viewData.title);
+
+ viewport->axesOn = yes;
+ viewport->regionOn = no;
+ viewport->monoOn = no;
+ viewport->zoomXOn = yes;
+ viewport->zoomYOn = yes;
+ viewport->zoomZOn = yes;
+
+ viewport->originrOn = yes;
+ viewport->objectrOn = no;
+ viewport->originFlag = no;
+
+ viewport->xyOn = no;
+ viewport->xzOn = no;
+ viewport->yzOn = no;
+
+ viewport->closing = no;
+ viewport->allowDraw = yes; /*if no, just draw axes the first time */
+ viewport->needNorm = yes;
+
+ viewport->lightVector[0] = -0.5;
+ viewport->lightVector[1] = 0.5;
+ viewport->lightVector[2] = 0.5;
+ viewport->translucency = viewData.translucency;
+
+ viewport->hueOffset = viewData.hueOff;
+ viewport->numberOfHues = viewData.numOfHues;
+ viewport->hueTop = viewData.hueOff + viewData.numOfHues;
+ if (viewport->hueTop > totalHues-1) viewport->hueTop = totalHues-1;
+ viewport->diagonals = viewData.diagonals;
+
+ /* make theta in [0..2pi) and phi in (-pi..pi] */
+ while (viewport->theta >= two_pi) {
+ viewport->theta -= two_pi;
+ }
+ while (viewport->theta < 0.0) {
+ viewport->theta += two_pi;
+ }
+ while (viewport->phi > pi) {
+ viewport->phi -= two_pi;
+ }
+ while (viewport->phi <= -pi) {
+ viewport->phi += two_pi;
+ }
+
+ while (viewport->axestheta >= two_pi) {
+ viewport->axestheta -= two_pi;
+ }
+ while (viewport->axestheta < 0.0) {
+ viewport->axestheta += two_pi;
+ }
+ while (viewport->axesphi > pi) {
+ viewport->axesphi -= two_pi;
+ }
+ while (viewport->axesphi <= -pi) {
+ viewport->axesphi += two_pi;
+ }
+
+ /* Initialize the rotation matrix about the origin. */
+ sinTheta = sin(-viewport->theta);
+ cosTheta = cos(-viewport->theta);
+ sinPhi = sin(viewport->phi);
+ cosPhi = cos(viewport->phi);
+ ROTATE(R); /* angles theta and phi are global */
+
+ /* Initialize the rotation matrix about the object's center of volume. */
+ sinTheta = sin(-viewport->thetaObj);
+ cosTheta = cos(-viewport->thetaObj);
+ sinPhi = sin(viewport->phiObj);
+ cosPhi = cos(viewport->phiObj);
+ ROTATE1(R1); /* angles theta and phi are global */
+
+
+ /* Initialize the non-uniform scaling matrix. */
+ SCALE(viewport->scaleX,viewport->scaleY,viewport->scaleZ,S);
+ /* Initialize the translation matrix. */
+ TRANSLATE(-viewport->deltaX,-viewport->deltaY,0.0,T);
+ /**** make the windows for the viewport ****/
+ spadbits = XCreateBitmapFromData(dsply,rtWindow,
+ spadBitmap_bits,
+ spadBitmap_width,spadBitmap_height);
+ spadmask = XCreateBitmapFromData(dsply,rtWindow,
+ spadMask_bits,
+ spadMask_width,spadMask_height);
+ viewAttrib.background_pixel = backgroundColor;
+ viewAttrib.border_pixel = foregroundColor;
+
+ viewAttrib.override_redirect = overrideManager;
+
+ viewAttrib.colormap = colorMap;
+ foreColor.pixel = foregroundColor;
+ backColor.pixel = backgroundColor;
+/*
+ foreColor.pixel = viewCursorForeground;
+ backColor.pixel = viewCursorBackground;
+*/
+ XQueryColor(dsply,colorMap,&foreColor);
+ XQueryColor(dsply,colorMap,&backColor);
+ viewAttrib.cursor = XCreatePixmapCursor(dsply,spadbits,spadmask,
+ &foreColor,&backColor,spadBitmap_x_hot,spadBitmap_y_hot);
+ viewAttrib.event_mask = titleMASK;
+ if (viewData.vW) {
+ titleSizeHints.flags = PPosition | PSize;
+ titleSizeHints.x = viewData.vX;
+ titleSizeHints.y = viewData.vY;
+ titleSizeHints.width = viewData.vW;
+ titleSizeHints.height = viewData.vH;
+ } else { /* ain't gonna allow this for now... */
+ titleSizeHints.flags = PSize;
+ titleSizeHints.width = viewWidth;
+ titleSizeHints.height = viewHeight;
+ }
+
+ viewTitleWindow = XCreateWindow(dsply /* display */,
+ rtWindow, /* parent */
+ viewData.vX, /* x */
+ viewData.vY, /* y */
+ viewData.vW, /* width */
+ viewData.vH, /* height */
+ /* viewBorderWidth+3*/ 0, /* border width */
+ CopyFromParent, /* depth */
+ InputOutput, /* class */
+ CopyFromParent, /* visual */
+ viewportTitleCreateMASK,/* valuemask */
+ &viewAttrib /* attributes */);
+
+ wm_delete_window = XInternAtom(dsply, "WM_DELETE_WINDOW", False);
+ (void) XSetWMProtocols(dsply, viewTitleWindow, &wm_delete_window, 1);
+
+ XSetNormalHints(dsply,viewTitleWindow,&titleSizeHints);
+ if (strlen(viewport->title) < 30)
+ XSetStandardProperties(dsply,viewTitleWindow,"AXIOM 3D",viewport->title,
+ None,NULL,0,&titleSizeHints);
+ else
+ XSetStandardProperties(dsply,viewTitleWindow,"AXIOM 3D","3D AXIOM Graph",
+ None,NULL,0,&titleSizeHints);
+ viewport->titleWindow = viewTitleWindow;
+
+ viewAttrib.event_mask = viewportMASK;
+ viewSizeHints.flags = PPosition | PSize;
+ viewSizeHints.x = -(viewBorderWidth+3);
+ viewSizeHints.x = 0; /* lose this */
+ viewSizeHints.y = titleHeight;
+ viewSizeHints.width = titleSizeHints.width;
+ viewSizeHints.height = titleSizeHints.height-(titleHeight+appendixHeight);
+
+ viewGraphWindow = XCreateWindow(dsply, /* display */
+ viewTitleWindow, /* parent */
+ viewSizeHints.x, /* x */
+ viewSizeHints.y, /* y */
+ viewSizeHints.width, /* width */
+ viewSizeHints.height, /* height */
+ /* viewBorderWidth+3*/0, /* border width */
+ CopyFromParent, /* depth */
+ InputOutput, /* class */
+ CopyFromParent, /* visual */
+ viewportCreateMASK, /* valuemask */
+ &viewAttrib /* attributes */);
+ XSetNormalHints(dsply,viewGraphWindow,&viewSizeHints);
+ XSetStandardProperties(dsply,viewGraphWindow,"","",None,NULL,0,
+ &viewSizeHints);
+ viewport->viewWindow = viewGraphWindow;
+ graphWindowAttrib.width = viewSizeHints.width;
+ graphWindowAttrib.height = viewSizeHints.height;
+
+ if (viewport->hueOffset != viewport->hueTop) {
+ multiColorFlag = yes;
+ redoColor = no;
+ } else {
+ if (viewport->hueTop < 11)
+ smoothHue = viewport->hueTop*6;
+ else {
+ if (viewport->hueTop > 10 && viewport->hueTop < 16)
+ smoothHue = viewport->hueTop*20 - 140;
+ else smoothHue = viewport->hueTop*12 - 12;
+ }
+ redoColor = yes;
+ }
+
+ /**** Make the control panel for the viewport. ****/
+
+ XSync(dsply,0);
+
+ control = viewport->controlPanel = makeControlPanel();
+ makeLightingPanel();
+ makeVolumePanel();
+ makeSavePanel();
+ makeQuitPanel();
+
+ if ((viewport->haveControl = viewData.showCP))
+ putControlPanelSomewhere(anywhere);
+
+ firstTime = yes;
+ return(viewport);
+
+} /* makeViewport() */
+
+
+/*****************************
+ * void postMakeViewport() *
+ * *
+ * post processing when *
+ * creating a viewport. *
+ * 1) assign min,max values *
+ * for the box volume *
+ *****************************/
+
+void
+#ifdef _NO_PROTO
+postMakeViewport ()
+#else
+postMakeViewport (void)
+#endif
+{
+
+ corners[0].x = viewData.xmin; corners[0].y = viewData.ymin;
+ corners[0].z = viewData.zmin;
+ corners[1].x = viewData.xmax; corners[1].y = viewData.ymin;
+ corners[1].z = viewData.zmin;
+ corners[2].x = viewData.xmax; corners[2].y = viewData.ymin;
+ corners[2].z = viewData.zmax;
+ corners[3].x = viewData.xmin; corners[3].y = viewData.ymin;
+ corners[3].z = viewData.zmax;
+ corners[4].x = viewData.xmin; corners[4].y = viewData.ymax;
+ corners[4].z = viewData.zmin;
+ corners[5].x = viewData.xmax; corners[5].y = viewData.ymax;
+ corners[5].z = viewData.zmin;
+ corners[6].x = viewData.xmax; corners[6].y = viewData.ymax;
+ corners[6].z = viewData.zmax;
+ corners[7].x = viewData.xmin; corners[7].y = viewData.ymax;
+ corners[7].z = viewData.zmax;
+
+ box[2].pointsPtr[0] = &(corners[0]);
+ box[2].pointsPtr[1] = &(corners[1]);
+ box[2].pointsPtr[2] = &(corners[2]);
+ box[2].pointsPtr[3] = &(corners[3]);
+
+ box[3].pointsPtr[0] = &(corners[1]);
+ box[3].pointsPtr[1] = &(corners[5]);
+ box[3].pointsPtr[2] = &(corners[6]);
+ box[3].pointsPtr[3] = &(corners[2]);
+
+ box[0].pointsPtr[0] = &(corners[4]);
+ box[0].pointsPtr[1] = &(corners[7]);
+ box[0].pointsPtr[2] = &(corners[6]);
+ box[0].pointsPtr[3] = &(corners[5]);
+
+ box[1].pointsPtr[0] = &(corners[0]);
+ box[1].pointsPtr[1] = &(corners[3]);
+ box[1].pointsPtr[2] = &(corners[7]);
+ box[1].pointsPtr[3] = &(corners[4]);
+
+ box[5].pointsPtr[0] = &(corners[3]);
+ box[5].pointsPtr[1] = &(corners[2]);
+ box[5].pointsPtr[2] = &(corners[6]);
+ box[5].pointsPtr[3] = &(corners[7]);
+
+ box[4].pointsPtr[0] = &(corners[0]);
+ box[4].pointsPtr[1] = &(corners[4]);
+ box[4].pointsPtr[2] = &(corners[5]);
+ box[4].pointsPtr[3] = &(corners[1]);
+
+ /* clip box */
+
+ clipBox[0].pointsPtr[0] = &(clipCorners[0]);
+ clipBox[0].pointsPtr[1] = &(clipCorners[1]);
+ clipBox[0].pointsPtr[2] = &(clipCorners[2]);
+ clipBox[0].pointsPtr[3] = &(clipCorners[3]);
+
+ clipBox[1].pointsPtr[0] = &(clipCorners[1]);
+ clipBox[1].pointsPtr[1] = &(clipCorners[5]);
+ clipBox[1].pointsPtr[2] = &(clipCorners[6]);
+ clipBox[1].pointsPtr[3] = &(clipCorners[2]);
+
+ clipBox[2].pointsPtr[0] = &(clipCorners[4]);
+ clipBox[2].pointsPtr[1] = &(clipCorners[7]);
+ clipBox[2].pointsPtr[2] = &(clipCorners[6]);
+ clipBox[2].pointsPtr[3] = &(clipCorners[5]);
+
+ clipBox[3].pointsPtr[0] = &(clipCorners[0]);
+ clipBox[3].pointsPtr[1] = &(clipCorners[3]);
+ clipBox[3].pointsPtr[2] = &(clipCorners[7]);
+ clipBox[3].pointsPtr[3] = &(clipCorners[4]);
+
+ clipBox[4].pointsPtr[0] = &(clipCorners[3]);
+ clipBox[4].pointsPtr[1] = &(clipCorners[2]);
+ clipBox[4].pointsPtr[2] = &(clipCorners[6]);
+ clipBox[4].pointsPtr[3] = &(clipCorners[7]);
+
+ clipBox[5].pointsPtr[0] = &(clipCorners[0]);
+ clipBox[5].pointsPtr[1] = &(clipCorners[4]);
+ clipBox[5].pointsPtr[2] = &(clipCorners[5]);
+ clipBox[5].pointsPtr[3] = &(clipCorners[1]);
+
+
+}
+
+
+/*****************************************
+ *** int keepDrawingViewport() ***
+ *****************************************/
+
+
+
+
+int
+#ifdef _NO_PROTO
+keepDrawingViewport()
+#else
+keepDrawingViewport(void)
+#endif
+{
+
+ XEvent peekEvent;
+ int retVal;
+
+ if (XPending(dsply)) {
+ XPeekEvent(dsply,&peekEvent);
+ if (((peekEvent.type == Expose) &&
+ ((peekEvent.xany).window == viewport->viewWindow)) ||
+ ((peekEvent.type == Expose) &&
+ ((peekEvent.xany).window == viewport->titleWindow)) ||
+ ((peekEvent.type == Expose) &&
+ ((peekEvent.xany).window == control->controlWindow))) {
+ retVal = firstTime;
+ } else if ((peekEvent.xbutton.type == ButtonRelease) ||
+ ((peekEvent.type == LeaveNotify) && !(followMouse)) ||
+ ((peekEvent.type == MotionNotify) && !(followMouse)) ||
+ (peekEvent.type == ResizeRequest)) {
+ XNextEvent(dsply,&peekEvent);
+ followMouse = no;
+ retVal = yes;
+ } else if ((peekEvent.xany).window == (control->buttonQueue[hideControl]).self) {
+ viewport->haveControl = no;
+ XUnmapWindow(dsply,control->controlWindow);
+ retVal = yes;
+ } else {
+ retVal = no;
+ }
+ } else {
+ retVal = !followMouse;
+ }
+
+ if (writeImage) retVal = yes;
+ drawMore = no;
+ return(retVal);
+
+}
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/volume.h b/src/graph/view3D/volume.h
new file mode 100755
index 00000000..35d60c42
--- /dev/null
+++ b/src/graph/view3D/volume.h
@@ -0,0 +1,169 @@
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+
+/*#define rightLeft*/
+#define leftRight
+#define newStuff
+
+ /******* Define's ********/
+ /*** box colors ***/
+#define boxInline monoColor(140)
+#define boxOutline monoColor(140)
+#define clipBoxInline monoColor(148)
+#define clipBoxOutline monoColor(148)
+
+#define lightB 205
+#define lightPotA (control->buttonQueue[lightMoveZ].buttonY - 15)
+#define lightPotB (control->buttonQueue[lightMoveZ].buttonY +\
+ control->buttonQueue[lightMoveZ].buttonHeight + 7)
+#define lightTransL (control->buttonQueue[lightTranslucent].buttonX - 20)
+
+#define volumeTitleColor monoColor(77)
+#define volumeTitleA 190
+#define volumeTitleB 217
+
+#define volumeMASK ExposureMask
+
+#define frustrumColor monoColor(147)
+#define frustrumX 30
+#define frustrumY 20
+#define frustrumLength 100
+#define frustrumMidY 70 /* frustrumY + frustrumLength/2 */
+#define frustrumBotY (frustrumY + frustrumLength)
+#ifdef newStuff
+#define frustrumMin (control->buttonQueue[frustrumBut].xHalf)
+#define frustrumMax (frustrumMin + \
+ (control->buttonQueue[frustrumBut].xHalf))
+#endif
+
+#define hitherColor monoColor(68) /* clipping plane */
+#define hitherMinX (frustrumX + 5)
+#define hitherMaxX (frustrumMin - 30)
+#define hitherWinX (hitherMinX - 5)
+#define hitherWinY (frustrumBotY + 10)
+#define hitherWidth (hitherMaxX - hitherMinX + 10)
+#define hitherHeight 20
+#define hitherBarY (hitherWinY + 10) /* hitherWinY + hitherHeight/2 */
+
+#ifdef newStuff
+#define eyeColor monoColor(131)
+#define eyeMinX frustrumMin
+#define eyeMaxX frustrumMax
+#define eyeWinX (eyeMinX - 5)
+#define eyeWinY hitherWinY
+#define eyeWidth (eyeMaxX - eyeMinX + 10)
+#define eyeHeight hitherHeight
+#define eyeBarY hitherBarY
+#endif
+
+#define volumeButtonColor monoColor(157)
+
+#define frustrumWindowX 30
+#define frustrumWindowY 28
+#define frustrumWindowWidth (controlWidth - 60)
+#define frustrumWindowHeight (frustrumBotY + 40)
+
+/**** clip volume ****/
+#define lengthFace 80
+#ifdef rightLeft
+#define backFaceX 190
+#endif
+#ifdef leftRight
+#define backFaceX 33
+#endif
+#define backFaceY 255
+#define deltaFace 25
+#define zLength 35.355 /* sqrt(2*deltaFace^2) */
+#ifdef rightLeft
+#define frontFaceX (backFaceX - deltaFace)
+#endif
+#ifdef leftRight
+#define frontFaceX (backFaceX + deltaFace)
+#endif
+#define frontFaceY (backFaceY + deltaFace)
+
+
+#define majorAxis lengthFace /* size of the potentiometers */
+#define minorAxis 20
+#define midAxis 40
+
+#define clipXButX backFaceX
+#define clipXButY (backFaceY-30)
+
+#ifdef rightLeft
+#define clipYButX (frontFaceX - minorAxis - 10)
+#endif
+#ifdef leftRight
+#define clipYButX (frontFaceX + lengthFace + 10)
+#endif
+#define clipYButY frontFaceY
+
+#ifdef rightLeft
+#define clipZButX clipYButX /* align left side */
+#endif
+#ifdef leftRight
+#define clipZButX (clipYButX+minorAxis-midAxis) /* align right side */
+#endif
+#define clipZButY clipXButY
+
+#define zFactor 0.6 /* ratio of clipZBut box & actual input area */
+#define minDistXY 0.1 /* min distance between normalized clip faces */
+#define minDistZ 0.06 /* 2/3 of XY */
+
+
+#ifdef rightLeft
+#define AA (clipZButX + midAxis)
+#define BB clipZButY
+#define CC backFaceX
+#define DD backFaceY
+#define EE frontFaceX
+#define FF frontFaceY
+#define clipZButTopEndX ((AA+BB+CC-DD)/2)
+#define clipZButTopEndY ((AA+BB-CC+DD)/2)
+#define clipZButBotEndX ((AA+BB+EE-FF)/2)
+#define clipZButBotEndY ((AA+BB-EE+FF)/2)
+#endif
+
+#ifdef leftRight
+#define AA clipZButX
+#define BB clipZButY
+#define CC (backFaceX + majorAxis)
+#define DD backFaceY
+#define EE (frontFaceX + majorAxis)
+#define FF frontFaceY
+
+#define clipZButTopEndX ((AA-BB+CC+DD)/2)
+#define clipZButTopEndY ((BB-AA+CC+DD)/2)
+#define clipZButBotEndX ((AA-BB+EE+FF)/2)
+#define clipZButBotEndY ((BB-AA+EE+FF)/2)
+#endif
diff --git a/src/graph/view3D/volume3d.c.pamphlet b/src/graph/view3D/volume3d.c.pamphlet
new file mode 100644
index 00000000..aef688cb
--- /dev/null
+++ b/src/graph/view3D/volume3d.c.pamphlet
@@ -0,0 +1,900 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D volume3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _VOLUME3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include <math.h>
+#include <string.h>
+
+#include "header.h"
+#include "cpanel.h"
+#include "process.h"
+#include "volume.h"
+#include "../include/purty/volume.bitmap"
+#include "../include/purty/volume.mask"
+
+
+
+#include "XSpadFill.H1"
+#include "Gfun.H1"
+#include "all_3d.H1"
+
+#define eyeDistMessX (frusX(eyeWinX+27))
+#define eyeDistMessY (frusY(eyeWinY-5))
+#define hitherMessX (frusX(hitherWinX+15))
+#define hitherMessY (frusY(hitherWinY))
+
+#define clipXMessX (control->buttonQueue[clipXBut].buttonX + \
+ control->buttonQueue[clipXBut].xHalf)
+#define clipXMessY (control->buttonQueue[clipXBut].buttonY + 2)
+#define clipYMessX (control->buttonQueue[clipYBut].buttonX + \
+ control->buttonQueue[clipYBut].buttonWidth-2)
+#define clipYMessY (control->buttonQueue[clipYBut].buttonY + \
+ control->buttonQueue[clipYBut].yHalf)
+#define clipZMessX (control->buttonQueue[clipZBut].buttonX + \
+ control->buttonQueue[clipZBut].xHalf+4)
+#define clipZMessY (control->buttonQueue[clipZBut].buttonY + \
+ control->buttonQueue[clipZBut].yHalf-4)
+
+#define volumeCursorForeground monoColor(68)
+#define volumeCursorBackground monoColor(197)
+
+#define hitherBoxColor monoColor(141)
+#define hitherBoxTop (frustrumMidY - 10)
+#define hitherBoxHeight 20
+
+#define clipButtonColor 144
+#define toggleColor 42
+#define arcColor 75
+
+#define arcSize 6
+#define tinyArc 5
+#define blank 4
+#define toggleX 190
+#define toggleY 280
+
+#define oldWay
+
+#define frusX(x) (control->buttonQueue[frustrumBut].buttonX + x)
+#define frusY(y) (control->buttonQueue[frustrumBut].buttonY + y)
+
+#define clipMessX 7
+#define clipMessY (control->buttonQueue[clipXBut].buttonY + 15)
+ /* someotherFont holds title font (see main.c) */
+#define clipMessDy (globalFont->max_bounds.ascent/2 + \
+ globalFont->max_bounds.descent)
+static char *clipMess = "Clip Volume";
+
+#define eyeMess1Dy clipMessDy
+#define eyeMess1X 7
+#define eyeMess1Y (frustrumY + 40 + 3*eyeMess1Dy)
+static char *eyeMess1 = "Eye";
+
+#define eyeMess2X (globalFont->max_bounds.width + 14)
+#define eyeMess2Y (frustrumY + 40)
+#define eyeMess2Dy eyeMess1Dy
+static char *eyeMess2 = "Reference";
+
+
+ /* global stuff */
+int flatClipBoxX[8], flatClipBoxY[8];
+
+
+
+
+/******************* volume buttons **********************/
+
+int
+#ifdef _NO_PROTO
+initVolumeButtons (volumeButtons)
+ buttonStruct *volumeButtons;
+#else
+initVolumeButtons (buttonStruct *volumeButtons)
+#endif
+{
+ int ii, num = 0;
+
+ ii = volumeReturn;
+ volumeButtons[ii].buttonX = 154;
+ volumeButtons[ii].buttonY = 370;
+ volumeButtons[ii].buttonWidth = 110;
+ volumeButtons[ii].buttonHeight = 24;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = no;
+ volumeButtons[ii].mask = buttonMASK;
+ volumeButtons[ii].text = "Return";
+ volumeButtons[ii].textColor = 52;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = volumeAbort;
+ volumeButtons[ii].buttonX = 36;
+ volumeButtons[ii].buttonY = 370;
+ volumeButtons[ii].buttonWidth = 110;
+ volumeButtons[ii].buttonHeight = 24;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = no;
+ volumeButtons[ii].mask = buttonMASK;
+ volumeButtons[ii].text = "Abort";
+ volumeButtons[ii].textColor = 28;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = frustrumBut;
+ volumeButtons[ii].buttonX = frustrumWindowX;
+ volumeButtons[ii].buttonY = frustrumWindowY;
+ volumeButtons[ii].buttonWidth = frustrumWindowWidth;
+ volumeButtons[ii].buttonHeight = frustrumWindowHeight;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = yes;
+ volumeButtons[ii].mask = potMASK;
+ volumeButtons[ii].text = "Frustrum Window";
+ volumeButtons[ii].textColor = frustrumColor;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = perspectiveBut;
+ volumeButtons[ii].buttonX = toggleX;
+ volumeButtons[ii].buttonY = toggleY;
+ volumeButtons[ii].buttonWidth = 10;
+ volumeButtons[ii].buttonHeight = 10;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = no;
+ volumeButtons[ii].mask = potMASK;
+ volumeButtons[ii].text = "Perspective";
+ volumeButtons[ii].textColor = arcColor;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = clipRegionBut;
+ volumeButtons[ii].buttonX = toggleX;
+ volumeButtons[ii].buttonY = toggleY+20;
+ volumeButtons[ii].buttonWidth = 10;
+ volumeButtons[ii].buttonHeight = 10;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = no;
+ volumeButtons[ii].mask = potMASK;
+ volumeButtons[ii].text = "Show Region";
+ volumeButtons[ii].textColor = arcColor;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = clipSurfaceBut;
+ volumeButtons[ii].buttonX = toggleX;
+ volumeButtons[ii].buttonY = toggleY+40;
+ volumeButtons[ii].buttonWidth = 10;
+ volumeButtons[ii].buttonHeight = 10;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = no;
+ volumeButtons[ii].mask = potMASK;
+ volumeButtons[ii].text = "Clipping On";
+ volumeButtons[ii].textColor = arcColor;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = clipXBut;
+ volumeButtons[ii].buttonX = clipXButX;
+ volumeButtons[ii].buttonY = clipXButY;
+ volumeButtons[ii].buttonWidth = majorAxis;
+ volumeButtons[ii].buttonHeight = minorAxis;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = yes;
+ volumeButtons[ii].mask = potMASK;
+ volumeButtons[ii].text = "Clip X";
+ volumeButtons[ii].textColor = clipButtonColor;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = clipYBut;
+ volumeButtons[ii].buttonX = clipYButX;
+ volumeButtons[ii].buttonY = clipYButY;
+ volumeButtons[ii].buttonWidth = minorAxis;
+ volumeButtons[ii].buttonHeight = majorAxis;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = yes;
+ volumeButtons[ii].mask = potMASK;
+ volumeButtons[ii].text = "Clip Y";
+ volumeButtons[ii].textColor = clipButtonColor;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = clipZBut;
+ volumeButtons[ii].buttonX = clipZButX;
+ volumeButtons[ii].buttonY = clipZButY;
+ volumeButtons[ii].buttonWidth = midAxis;
+ volumeButtons[ii].buttonHeight = midAxis;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = yes;
+ volumeButtons[ii].mask = potMASK;
+ volumeButtons[ii].text = "Clip Z";
+ volumeButtons[ii].textColor = clipButtonColor;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ return(num);
+}
+
+
+/*************************
+ * int makeVolumePanel() *
+ *************************/
+
+void
+#ifdef _NO_PROTO
+makeVolumePanel ()
+#else
+makeVolumePanel (void)
+#endif
+{
+
+ int i;
+ XSetWindowAttributes cwAttrib, controlAttrib;
+ XSizeHints sizehint;
+ Pixmap volumebits, volumemask;
+ XColor foreColor, backColor;
+
+ volumebits = XCreateBitmapFromData(dsply,rtWindow,volumeBitmap_bits,
+ volumeBitmap_width,volumeBitmap_height);
+ volumemask = XCreateBitmapFromData(dsply,rtWindow,volumeMask_bits,
+ volumeMask_width,volumeMask_height);
+ cwAttrib.background_pixel = backgroundColor;
+ cwAttrib.border_pixel = foregroundColor;
+ cwAttrib.event_mask = volumeMASK;
+ cwAttrib.colormap = colorMap;
+ cwAttrib.override_redirect = overrideManager;
+ foreColor.pixel = volumeCursorForeground;
+ XQueryColor(dsply,colorMap,&foreColor);
+ backColor.pixel = volumeCursorBackground;
+ XQueryColor(dsply,colorMap,&backColor);
+ cwAttrib.cursor = XCreatePixmapCursor(dsply,volumebits,volumemask,
+ &foreColor,&backColor,
+ volumeBitmap_x_hot,
+ volumeBitmap_y_hot);
+ volumeWindow = XCreateWindow(dsply,control->controlWindow,
+ -3,-3,controlWidth,controlHeight,3,
+ CopyFromParent,InputOutput,CopyFromParent,
+ controlCreateMASK,&cwAttrib);
+
+ sizehint.flags = USPosition | USSize;
+ sizehint.x = 0;
+ sizehint.y = 0;
+ sizehint.width = controlWidth;
+ sizehint.height = controlHeight;
+ /*** the None stands for icon pixmap ***/
+ XSetNormalHints(dsply,volumeWindow,&sizehint);
+ XSetStandardProperties(dsply,volumeWindow,"Volume Panel 3D",
+ "View Volume",None,NULL,0,&sizehint);
+
+ /*** volume frustrum window ***/
+
+ /*** do volume buttons ***/
+ initVolumeButtons(control->buttonQueue);
+ for (i=volumeButtonsStart; i<(volumeButtonsEnd); i++) {
+ controlAttrib.event_mask = (control->buttonQueue[i]).mask;
+ (control->buttonQueue[i]).self =
+ XCreateWindow(dsply,volumeWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,
+ 0,0,InputOnly,CopyFromParent,
+ buttonCreateMASK,&controlAttrib);
+ XMakeAssoc(dsply,table,(control->buttonQueue[i]).self,
+ &((control->buttonQueue[i]).buttonKey));
+ XMapWindow(dsply,(control->buttonQueue[i]).self);
+ }
+
+} /* makeVolumePanel() */
+
+
+void
+#ifdef _NO_PROTO
+drawClipXBut ()
+#else
+drawClipXBut (void)
+#endif
+{
+
+ XClearArea(dsply,volumeWindow,clipXButX,clipXButY,
+ majorAxis+blank,minorAxis+blank,False);
+ GSetForeground(trashGC,(float)monoColor(toggleColor),Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipXBut]).buttonX,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf,
+ (control->buttonQueue[clipXBut]).buttonX +
+ (control->buttonQueue[clipXBut]).buttonWidth,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipXBut]).buttonX-3,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf-3,
+ (control->buttonQueue[clipXBut]).buttonX,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipXBut]).buttonX-3,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf+3,
+ (control->buttonQueue[clipXBut]).buttonX,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipXBut]).buttonX +
+ (control->buttonQueue[clipXBut]).buttonWidth+3,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf-3,
+ (control->buttonQueue[clipXBut]).buttonX +
+ (control->buttonQueue[clipXBut]).buttonWidth,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipXBut]).buttonX +
+ (control->buttonQueue[clipXBut]).buttonWidth+3,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf+3,
+ (control->buttonQueue[clipXBut]).buttonX +
+ (control->buttonQueue[clipXBut]).buttonWidth,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf,Xoption);
+
+ GSetForeground(trashGC,(float)monoColor(arcColor),Xoption);
+ GFillArc(trashGC,volumeWindow,
+ (int)(xClipMinN * (majorAxis-tinyArc) + clipXButX), /* x value */
+ (int)(clipXButY + minorAxis/2 + 1), /* y value */
+ arcSize,arcSize,0,360*64,Xoption); /* 64 units per degree */
+ GFillArc(trashGC,volumeWindow,
+ (int)(xClipMaxN * (majorAxis-tinyArc) + clipXButX), /* x value */
+ (int)(clipXButY + minorAxis/2 - 7), /* y value */
+ arcSize,arcSize,0,360*64,Xoption); /* 64 units per degree */
+
+ GSetForeground(volumeGC,(float)monoColor(toggleColor),Xoption);
+ GDrawString(volumeGC,volumeWindow,clipXMessX,clipXMessY,"X",1,Xoption);
+
+}
+
+void
+#ifdef _NO_PROTO
+drawClipYBut ()
+#else
+drawClipYBut (void)
+#endif
+{
+
+ XClearArea(dsply,volumeWindow,clipYButX,clipYButY,
+ minorAxis+blank,majorAxis+blank,False);
+ GSetForeground(trashGC,(float)monoColor(toggleColor),Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf,
+ (control->buttonQueue[clipYBut]).buttonY,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf,
+ (control->buttonQueue[clipYBut]).buttonY +
+ (control->buttonQueue[clipYBut]).buttonHeight,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf-3,
+ (control->buttonQueue[clipYBut]).buttonY-3,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf,
+ (control->buttonQueue[clipYBut]).buttonY,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf+3,
+ (control->buttonQueue[clipYBut]).buttonY-3,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf,
+ (control->buttonQueue[clipYBut]).buttonY,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf-3,
+ (control->buttonQueue[clipYBut]).buttonY +
+ (control->buttonQueue[clipYBut]).buttonHeight+3,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf,
+ (control->buttonQueue[clipYBut]).buttonY +
+ (control->buttonQueue[clipYBut]).buttonHeight,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf+3,
+ (control->buttonQueue[clipYBut]).buttonY +
+ (control->buttonQueue[clipYBut]).buttonHeight+3,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf,
+ (control->buttonQueue[clipYBut]).buttonY +
+ (control->buttonQueue[clipYBut]).buttonHeight,Xoption);
+
+ GSetForeground(trashGC,(float)monoColor(arcColor),Xoption);
+
+ /* note: minimum buttons closer to the box */
+ GFillArc(trashGC,volumeWindow,
+ (int)(clipYButX + minorAxis/2 - 8),
+ (int)(yClipMinN * (majorAxis-tinyArc) + clipYButY),
+ arcSize,arcSize,90*64,360*64,Xoption); /* 64 units per degree */
+ GFillArc(trashGC,volumeWindow,
+ (int)(clipYButX + minorAxis/2 + 3),
+ (int)(yClipMaxN * (majorAxis-tinyArc) + clipYButY),
+ arcSize,arcSize,90*64,360*64,Xoption); /* 64 units per degree */
+
+ GSetForeground(volumeGC,(float)monoColor(toggleColor),Xoption);
+ GDrawString(volumeGC,volumeWindow,clipYMessX,clipYMessY,"Y",1,Xoption);
+
+}
+
+
+void
+#ifdef _NO_PROTO
+drawClipZBut ()
+#else
+drawClipZBut (void)
+#endif
+{
+
+ XClearArea(dsply,volumeWindow,clipZButX,clipZButY,
+ midAxis+blank,midAxis+blank,False);
+ GSetForeground(trashGC,(float)monoColor(toggleColor),Xoption);
+ GDrawLine(trashGC,volumeWindow,clipZButTopEndX,clipZButTopEndY,
+ clipZButBotEndX,clipZButBotEndY,Xoption);
+ GDrawLine(trashGC,volumeWindow,clipZButTopEndX-4,clipZButTopEndY,
+ clipZButTopEndX,clipZButTopEndY,Xoption);
+
+ GDrawLine(trashGC,volumeWindow,clipZButTopEndX,clipZButTopEndY-4,
+ clipZButTopEndX,clipZButTopEndY,Xoption);
+
+ GDrawLine(trashGC,volumeWindow,clipZButBotEndX+4,clipZButBotEndY,
+ clipZButBotEndX,clipZButBotEndY,Xoption);
+
+ GDrawLine(trashGC,volumeWindow,clipZButBotEndX,clipZButBotEndY+4,
+ clipZButBotEndX,clipZButBotEndY,Xoption);
+
+
+ GSetForeground(trashGC,(float)monoColor(arcColor),Xoption);
+ GFillArc(trashGC,volumeWindow,
+ (int)(zClipMinN * midAxis * zFactor + clipZButTopEndX - 3),
+ (int)(zClipMinN * midAxis * zFactor + clipZButTopEndY + 3),
+ arcSize,arcSize,45*64,360*64,Xoption); /* 64 units per degree */
+ GFillArc(trashGC,volumeWindow,
+ (int)(zClipMaxN * midAxis * zFactor + clipZButTopEndX + 3),
+ (int)(zClipMaxN * midAxis * zFactor + clipZButTopEndY - 5),
+ arcSize,arcSize,45*64,360*64,Xoption); /* 64 units per degree */
+
+ GSetForeground(volumeGC,(float)monoColor(toggleColor),Xoption);
+ GDrawString(volumeGC,volumeWindow,clipZMessX,clipZMessY,"Z",1,Xoption);
+
+}
+
+
+void
+#ifdef _NO_PROTO
+drawClipVolume ()
+#else
+drawClipVolume (void)
+#endif
+{
+
+ float xminL,xmaxL,yminL,ymaxL,zminL,zmaxL;
+
+ XClearArea(dsply,volumeWindow,backFaceX-1,backFaceY,
+ lengthFace+deltaFace+2,lengthFace+deltaFace+1,False);
+
+ GSetForeground(trashGC,(float)boxInline,Xoption); /*boxOutline=133*/
+ GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,Xoption);
+
+ /* define corners of volume, clockwise, back to front */
+ xminL = xClipMinN*lengthFace;
+ xmaxL = xClipMaxN*lengthFace;
+ yminL = yClipMinN*lengthFace;
+ ymaxL = yClipMaxN*lengthFace;
+ zminL = zClipMinN*zLength;
+ zmaxL = (1-zClipMaxN)*zLength; /* percentage upwards from bottom */
+
+ flatClipBoxX[0] = backFaceX + xminL + zminL;
+ flatClipBoxY[0] = backFaceY + yminL + zminL;
+ flatClipBoxX[1] = backFaceX + xmaxL + zminL;
+ flatClipBoxY[1] = flatClipBoxY[0];
+ flatClipBoxX[2] = flatClipBoxX[1];
+ flatClipBoxY[2] = backFaceY + ymaxL + zminL;
+ flatClipBoxX[3] = flatClipBoxX[0];
+ flatClipBoxY[3] = flatClipBoxY[2];
+ flatClipBoxX[4] = frontFaceX + xminL - zmaxL;
+ flatClipBoxY[4] = frontFaceY + yminL - zmaxL;
+ flatClipBoxX[5] = frontFaceX + xmaxL - zmaxL;
+ flatClipBoxY[5] = flatClipBoxY[4];
+ flatClipBoxX[6] = flatClipBoxX[5];
+ flatClipBoxY[6] = frontFaceY + ymaxL - zmaxL;
+ flatClipBoxX[7] = flatClipBoxX[4];
+ flatClipBoxY[7] = flatClipBoxY[6];
+
+ /* now draw the volume */
+ GDrawRectangle(trashGC,volumeWindow,
+ flatClipBoxX[0],flatClipBoxY[0],
+ flatClipBoxX[2]-flatClipBoxX[0],
+ flatClipBoxY[2]-flatClipBoxY[0],Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ flatClipBoxX[0],flatClipBoxY[0],flatClipBoxX[4],flatClipBoxY[4],Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ flatClipBoxX[1],flatClipBoxY[1],flatClipBoxX[5],flatClipBoxY[5],Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ flatClipBoxX[2],flatClipBoxY[2],flatClipBoxX[6],flatClipBoxY[6],Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ flatClipBoxX[3],flatClipBoxY[3],flatClipBoxX[7],flatClipBoxY[7],Xoption);
+ GSetForeground(trashGC,(float)boxOutline,Xoption);
+ GDrawRectangle(trashGC,volumeWindow,
+ flatClipBoxX[4],flatClipBoxY[4],
+ flatClipBoxX[6]-flatClipBoxX[4],
+ flatClipBoxY[6]-flatClipBoxY[4],Xoption);
+ /* make sure volumeGC is set properly before calling these functions */
+
+} /* drawClipVolume() */
+
+
+void
+#ifdef _NO_PROTO
+drawHitherControl ()
+#else
+drawHitherControl (void)
+#endif
+{
+
+ float xx,b,slope;
+ int hitherTop, hitherBot;
+
+ float b0x,b1x;
+
+ /* draw box indicating minimum and maximum distance of projection */
+ GSetForeground(trashGC,(float)hitherBoxColor,Xoption);
+ b0x = (pzMin - clipPlaneMin)/(clipPlaneMax-clipPlaneMin);
+ b0x = hitherMaxX - b0x*(hitherMaxX - hitherMinX); /* screen x */
+ b1x = (pzMax - clipPlaneMin)/(clipPlaneMax-clipPlaneMin);
+ b1x = hitherMaxX - b1x*(hitherMaxX - hitherMinX); /* screen x */
+ GDraw3DButtonOut(trashGC,volumeWindow,
+ (int)(b0x),frusY(hitherBoxTop),
+ (int)fabs(b1x-b0x),hitherBoxHeight,Xoption);
+
+ /* draw the hither plane */
+ GSetForeground(trashGC,(float)hitherColor,Xoption);
+
+ /* percentage x */
+ xx = ((viewData.clipPlane-clipPlaneMin)/(clipPlaneMax-clipPlaneMin));
+ xx = hitherMaxX - xx*(hitherMaxX - hitherMinX); /* screen x */
+ slope = ((float)frustrumY - frustrumMidY)/(frustrumX - frustrumVertex);
+ b = ((float)frustrumX*frustrumMidY - frustrumVertex*frustrumY) /
+ (frustrumX - frustrumVertex);
+ hitherTop = slope * xx + b + 0.5;
+ slope = (float)(frustrumBotY - frustrumMidY)/(frustrumX - frustrumVertex);
+ b = ((float)frustrumX*frustrumMidY - frustrumVertex*frustrumBotY) /
+ (frustrumX - frustrumVertex);
+ hitherBot = slope * xx + b + 0.5;
+ GDrawLine(trashGC,volumeWindow, frusX((int)xx),frusY(hitherTop),
+ frusX((int)xx),frusY(hitherBot),Xoption);
+
+ /* draw hither control box and bar */
+ GDraw3DButtonOut(trashGC,volumeWindow,
+ frusX(hitherWinX),frusY(hitherWinY+5),
+ hitherWidth,hitherHeight,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(hitherMinX),frusY(hitherBarY+5),
+ frusX(hitherMaxX),frusY(hitherBarY+5),Xoption);
+ /* draw hither plane I/O pointer arrow */
+
+ GDrawLine(trashGC,volumeWindow,
+ frusX((int)xx),frusY(hitherBarY+2),
+ frusX((int)xx),frusY(hitherBarY+8),Xoption);
+
+ /* print string label */
+ GSetForeground(volumeGC,(float)hitherColor,Xoption);
+ GDrawString(volumeGC,volumeWindow,hitherMessX,hitherMessY,"Hither",6,Xoption);
+
+}
+
+void
+#ifdef _NO_PROTO
+drawEyeControl ()
+#else
+drawEyeControl (void)
+#endif
+{
+
+ float here;
+ int there;
+
+ GSetForeground(trashGC,(float)eyeColor,Xoption);
+
+ /* draw the eyeDistance box & slide bar */
+ GDraw3DButtonOut(trashGC,volumeWindow,
+ frusX(eyeWinX),frusY(eyeWinY+5),eyeWidth,eyeHeight,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(eyeMinX),frusY(eyeBarY+5),frusX(eyeMaxX),frusY(eyeBarY+5),Xoption);
+ here = (viewData.eyeDistance - minEyeDistance) /
+ (maxEyeDistance - minEyeDistance);
+ here = pow((double)here,0.333333);
+ there = here * (eyeMaxX - eyeMinX) + eyeMinX; /* screen x */
+ GDrawLine(trashGC,volumeWindow,
+ frusX(there),frusY(eyeBarY+2),frusX(there),frusY(eyeBarY+8),Xoption);
+
+ /* draw the eye */
+ GSetLineAttributes(trashGC,2,LineSolid,CapButt,JoinMiter,Xoption);
+ GSetForeground(trashGC,(float)monoColor(52),Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(there),frusY(frustrumMidY-5),
+ frusX(there+8),frusY(frustrumMidY),Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(there+2),frusY(frustrumMidY+4),
+ frusX(there+8),frusY(frustrumMidY-1),Xoption);
+ GSetForeground(trashGC,(float)frustrumColor,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(there+4),frusY(frustrumMidY-3),
+ frusX(there+2),frusY(frustrumMidY),Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(there+4),frusY(frustrumMidY+2),
+ frusX(there+3),frusY(frustrumMidY),Xoption);
+ GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,Xoption);
+
+ /* draw string label */
+ GSetForeground(volumeGC,(float)eyeColor,Xoption);
+ GDrawString(volumeGC,volumeWindow,eyeDistMessX,eyeDistMessY,
+ "Eye Distance",strlen("eye distance"),Xoption);
+
+}
+
+
+/**************************
+ * void drawFrustrum() *
+ **************************/
+
+void
+#ifdef _NO_PROTO
+drawFrustrum ()
+#else
+drawFrustrum (void)
+#endif
+{
+
+ float normalizedEyeDistance;
+
+ XClearArea(dsply,volumeWindow,
+ control->buttonQueue[frustrumBut].buttonX,
+ control->buttonQueue[frustrumBut].buttonY,
+ control->buttonQueue[frustrumBut].buttonWidth+9,
+ control->buttonQueue[frustrumBut].buttonHeight,False);
+ GSetForeground(trashGC,(float)frustrumColor,Xoption);
+ normalizedEyeDistance = (viewData.eyeDistance - minEyeDistance) /
+ (maxEyeDistance - minEyeDistance);
+ normalizedEyeDistance = pow((double)normalizedEyeDistance,0.333333333);
+ frustrumVertex = normalizedEyeDistance * (frustrumMax - frustrumMin) +
+ frustrumMin - 4;
+ GDrawLine(trashGC,volumeWindow,
+ frusX(frustrumX),frusY(frustrumY),
+ frusX(frustrumX),frusY(frustrumY+frustrumLength),Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(frustrumX),frusY(frustrumY),
+ frusX(frustrumVertex),frusY(frustrumMidY),Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(frustrumX),frusY(frustrumBotY),
+ frusX(frustrumVertex),frusY(frustrumMidY),Xoption);
+
+ /* draw controls */
+ drawHitherControl();
+ drawEyeControl();
+
+} /* drawFrustrum() */
+
+
+
+/**************************
+ * void drawVolumePanel() *
+ **************************/
+
+void
+#ifdef _NO_PROTO
+drawVolumePanel ()
+#else
+drawVolumePanel (void)
+#endif
+{
+
+ int i,strlength;
+
+
+ /* Draw some lines for volume panel. */
+ GSetForeground(trashGC,(float)foregroundColor,Xoption);
+ GSetLineAttributes(trashGC,3,LineSolid,CapButt,JoinMiter,Xoption);
+ GDrawLine(trashGC, volumeWindow, 0, potA, controlWidth, potA, Xoption);
+
+ GSetLineAttributes(trashGC,2,LineSolid,CapButt,JoinMiter,Xoption);
+ GDrawLine(trashGC, volumeWindow, 0, volumeTitleA, controlWidth,
+ volumeTitleA, Xoption);
+ GDrawLine(trashGC, volumeWindow, 0, volumeTitleB, controlWidth,
+ volumeTitleB, Xoption);
+
+ writeControlTitle(volumeWindow);
+ s = "Viewing Volume Panel";
+ strlength = strlen(s);
+ GSetForeground(anotherGC,(float)volumeTitleColor,Xoption);
+ GDrawString(anotherGC,volumeWindow,
+ centerX(anotherGC,s,strlength,controlWidth),
+ volumeTitleA+18,s,strlength,Xoption);
+
+ GSetForeground(anotherGC,(float)monoColor(toggleColor),Xoption);
+ GDrawString(anotherGC,volumeWindow,
+ control->buttonQueue[perspectiveBut].buttonX + 4,
+ control->buttonQueue[perspectiveBut].buttonY - 17,
+ "Settings", 8, Xoption);
+
+ GSetForeground(trashGC,(float)monoColor(toggleColor),Xoption);
+ GDraw3DButtonOut(trashGC,volumeWindow,
+ control->buttonQueue[perspectiveBut].buttonX - 7,
+ control->buttonQueue[perspectiveBut].buttonY - 36,
+ 100,100,Xoption);
+
+
+ for (i=0; i<strlen(clipMess); i++)
+ GDrawString(trashGC,volumeWindow,clipMessX,clipMessY + i*clipMessDy,
+ &(clipMess[i]),1,Xoption);
+ for (i=0; i<strlen(eyeMess1); i++)
+ GDrawString(trashGC,volumeWindow,eyeMess1X,eyeMess1Y + i*eyeMess1Dy,
+ &(eyeMess1[i]),1,Xoption);
+ for (i=0; i<strlen(eyeMess2); i++)
+ GDrawString(trashGC,volumeWindow,eyeMess2X,eyeMess2Y + i*eyeMess2Dy,
+ &(eyeMess2[i]),1,Xoption);
+
+ GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,Xoption);
+ GSetForeground(trashGC,(float)volumeButtonColor,Xoption);
+ for (i=volumeButtonsStart; i<(volumeButtonsEnd); i++) {
+ GSetForeground(trashGC,
+ (float)monoColor((control->buttonQueue[i]).textColor),Xoption);
+ switch (i) {
+ case perspectiveBut:
+ case clipRegionBut:
+ case clipSurfaceBut:
+ GSetForeground(volumeGC,(float)monoColor(toggleColor),Xoption);
+ GDraw3DButtonOut(volumeGC,volumeWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,Xoption);
+ GSetForeground(volumeGC,
+ (float)monoColor((control->buttonQueue[i]).textColor),Xoption);
+ GDrawString(volumeGC,volumeWindow,
+ (control->buttonQueue[i]).buttonX +
+ (control->buttonQueue[i]).buttonWidth + 4,
+ (control->buttonQueue[i]).buttonY +
+ centerY(volumeGC,(control->buttonQueue[i]).buttonHeight),
+ (control->buttonQueue[i]).text,
+ strlen(control->buttonQueue[i].text),Xoption);
+ if (i==perspectiveBut && viewData.perspective)
+ GDrawString(volumeGC,volumeWindow,
+ (control->buttonQueue[i]).buttonX +
+ centerX(volumeGC,"x",1,
+ (control->buttonQueue[i]).buttonWidth),
+ (control->buttonQueue[i]).buttonY +
+ centerY(volumeGC,(control->buttonQueue[i]).buttonHeight),
+ "x",1,Xoption);
+ else if (i==clipRegionBut && viewData.clipbox)
+ GDrawString(volumeGC,volumeWindow,
+ (control->buttonQueue[i]).buttonX +
+ centerX(volumeGC,"x",1,
+ (control->buttonQueue[i]).buttonWidth),
+ (control->buttonQueue[i]).buttonY +
+ centerY(volumeGC,(control->buttonQueue[i]).buttonHeight),
+ "x",1,Xoption);
+ else if (i==clipSurfaceBut && viewData.clipStuff)
+ GDrawString(volumeGC,volumeWindow,
+ (control->buttonQueue[i]).buttonX +
+ centerX(volumeGC,"x",1,
+ (control->buttonQueue[i]).buttonWidth),
+ (control->buttonQueue[i]).buttonY +
+ centerY(volumeGC,(control->buttonQueue[i]).buttonHeight),
+ "x",1,Xoption);
+
+ break;
+
+ case clipXBut:
+ drawClipXBut();
+ break;
+
+ case clipYBut:
+ drawClipYBut();
+ break;
+
+ case clipZBut:
+ drawClipZBut();
+ break;
+
+ case frustrumBut:
+ break;
+
+ default:
+ GDraw3DButtonOut(trashGC,volumeWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,Xoption);
+ s = (control->buttonQueue[i]).text;
+ strlength = strlen(s);
+ GSetForeground(trashGC,
+ (float)monoColor((control->buttonQueue[i]).textColor),Xoption);
+ GDrawString(trashGC,volumeWindow,
+ (control->buttonQueue[i]).buttonX +
+ centerX(processGC,s,strlength,
+ (control->buttonQueue[i]).buttonWidth),
+ (control->buttonQueue[i]).buttonY +
+ centerY(processGC,(control->buttonQueue[i]).buttonHeight),
+ s,strlen(s),Xoption);
+ } /* switch */
+ } /* for i in volumeButtons */
+
+ drawFrustrum();
+ drawClipVolume(); /*** put in header ***/
+ drawClipXBut();
+ drawClipYBut();
+ drawClipZBut();
+
+} /* drawVolumePanel() */
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/graph/view3D/write3d.c.pamphlet b/src/graph/view3D/write3d.c.pamphlet
new file mode 100644
index 00000000..d332473d
--- /dev/null
+++ b/src/graph/view3D/write3d.c.pamphlet
@@ -0,0 +1,236 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/graph/view3D write3d.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+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 Numerical ALgorithms Group Ltd. 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.
+*/
+@
+<<*>>=
+<<license>>
+
+#define _WRITE3D_C
+#include "axiom-c-macros.h"
+#include "useproto.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "header.h"
+#include "write.h"
+#include "mode.h"
+
+
+#include "pixmap.H1"
+#include "XShade.H1"
+#include "Gfun.H1"
+
+#include "all_3d.H1"
+
+ /* upper limit as to how many kinds of files could be written (numBits-1) */
+#define numBits (8*sizeof(int))
+#define StellarColors 9
+
+int
+#ifdef _NO_PROTO
+writeViewport (thingsToWrite)
+ int thingsToWrite;
+#else
+writeViewport (int thingsToWrite)
+#endif
+{
+
+ int i, j, k, ii, code, *anIndex;
+ LLPoint *anLLPoint;
+ LPoint *anLPoint;
+ viewTriple *aPt;
+ XWindowAttributes vwInfo;
+ FILE *viewDataFile;
+ char viewDirName[80], viewDataFilename[80],
+ viewBitmapFilename[80], viewPixmapFilename[80],
+ command[80];
+
+ XGetWindowAttributes(dsply,viewport->titleWindow,&vwInfo);
+ sprintf(viewDirName,"%s%s",filename,".VIEW");
+ sprintf(command,"%s%s%s","rm -r ",viewDirName," > /dev/null 2>&1");
+ code = system(command);
+ sprintf(command,"%s%s%s","mkdir ",viewDirName," > /dev/null 2>&1");
+ system(command);
+ if (0) {
+ fprintf(stderr," Error: Cannot create %s\n",viewDirName);
+ return(-1);
+ } else {
+
+ /*** Create the data file ***/
+ sprintf(viewDataFilename,"%s%s",viewDirName,"/data");
+ if ((viewDataFile = fopen(viewDataFilename,"w")) == NULL) {
+ fprintf(stderr," Error: Cannot create %s\n",viewDataFilename);
+ perror("fopen");
+ return(-1);
+ } else {
+ /*** write out the view3DStruct stuff ***/
+ fprintf(viewDataFile,"%d\n",viewData.typeOf3D);
+ fprintf(viewDataFile,"%g %g %g %g %g %g\n",
+ viewData.xmin,viewData.xmax,viewData.ymin,viewData.ymax,
+ viewData.zmin,viewData.zmax);
+ fprintf(viewDataFile,"%s\n",viewport->title);
+ fprintf(viewDataFile,"%g %g %g %g %g %g %g %g\n",viewport->deltaX,
+ viewport->deltaY,viewport->scale,
+ viewport->scaleX,viewport->scaleY,viewport->scaleZ,
+ viewport->theta,viewport->phi);
+ fprintf(viewDataFile,"%d %d %d %d\n",vwInfo.x,vwInfo.y,vwInfo.width,
+ vwInfo.height);
+ fprintf(viewDataFile,"%d %d %d %d %d %d %d\n",viewport->haveControl,
+ viewData.style, viewport->axesOn,
+ viewport->hueOffset,viewport->numberOfHues,
+ viewport->diagonals, viewData.outlineRenderOn);
+ fprintf(viewDataFile,"%g %g %g %g\n",viewport->lightVector[0],
+ viewport->lightVector[1], viewport->lightVector[2],
+ viewport->translucency);
+ fprintf(viewDataFile,"%d %g\n",viewData.perspective,
+ viewData.eyeDistance);
+
+ /* write out the generalized 3D components */
+ fprintf(viewDataFile,"%d\n",viewData.numOfPoints);
+ for (i=0; i<viewData.numOfPoints; i++) {
+ aPt = refPt3D(viewData,i);
+ fprintf(viewDataFile,"%g %g %g %g\n",aPt->x, aPt->y, aPt->z, aPt->c);
+ }
+ fprintf(viewDataFile,"%d\n",viewData.lllp.numOfComponents);
+ anLLPoint = viewData.lllp.llp;
+ for (i=0; i<viewData.lllp.numOfComponents; i++,anLLPoint++) {
+ fprintf(viewDataFile,"%d %d\n",anLLPoint->prop.closed,
+ anLLPoint->prop.solid);
+ fprintf(viewDataFile,"%d\n",anLLPoint->numOfLists);
+ anLPoint = anLLPoint->lp;
+ for (j=0; j<anLLPoint->numOfLists; j++,anLPoint++) {
+ fprintf(viewDataFile,"%d %d\n",anLPoint->prop.closed,
+ anLPoint->prop.solid);
+ fprintf(viewDataFile,"%d\n",anLPoint->numOfPoints);
+ anIndex = anLPoint->indices;
+ for (k=0; k<anLPoint->numOfPoints; k++,anIndex++) {
+ fprintf(viewDataFile,"%d\n",*anIndex);
+ } /* for points in LPoints (k) */
+ } /* for LPoints in LLPoints (j) */
+ } /* for LLPoints in LLLPoints (i) */
+ fclose(viewDataFile);
+ } /* else was able to open file under the given filename */
+
+ /* write out special files */
+ for (ii=1; ii<numBits; ii++) { /* write.h is one-based */
+ if (thingsToWrite & (1<<ii)) {
+ switch (ii) {
+ case Bitmap:
+ /*** Create the pixmap (bitmaps need leaf name) ***/
+ sprintf(viewBitmapFilename,"%s%s%s",viewDirName,"/","image.bm");
+ XGetWindowAttributes(dsply,viewport->viewWindow,&vwInfo);
+ code = XWriteBitmapFile(dsply,viewBitmapFilename,
+ viewport->titleWindow,vwInfo.width,
+ vwInfo.height+vwInfo.border_width+20,-1,-1);
+ break;
+
+ case Pixmap:
+ /*** Create the pixmap (bitmaps need leaf name) ***/
+ sprintf(viewPixmapFilename,"%s%s%s",viewDirName,"/","image.xpm");
+ XGetWindowAttributes(dsply,viewport->viewWindow,&vwInfo);
+ write_pixmap_file(dsply,scrn,viewPixmapFilename,
+ viewport->titleWindow,0,0,vwInfo.width,
+ vwInfo.height+titleHeight);
+ break;
+
+ case Image:
+ /*** Create the image (bitmaps need leaf name) ***/
+ writeImage = yes;
+ sprintf(viewPixmapFilename,"%s%s%s",viewDirName,"/","image.xpm");
+ XResizeWindow(dsply,viewport->titleWindow,300,300+titleHeight);
+ XResizeWindow(dsply,viewport->viewWindow,300,300);
+ viewport->hueTop = totalHues-1; viewport->hueOffset = 0;
+ viewport->numberOfHues = viewport->hueTop - viewport->hueOffset;
+ firstTime = 1;
+ if (viewData.style == transparent) {
+ viewData.style = render;
+ viewData.outlineRenderOn = 1;
+ } else {
+ if (viewData.style == render) viewData.outlineRenderOn = 1;
+ }
+ drawViewport(Xoption);
+ writeTitle();
+ XGetWindowAttributes(dsply,viewport->viewWindow,&vwInfo);
+ write_pixmap_file(dsply,scrn,viewPixmapFilename,
+ viewport->titleWindow,0,0,vwInfo.width,
+ vwInfo.height+titleHeight);
+ viewport->monoOn = 1;
+ maxGreyShade = XInitShades(dsply,scrn);
+ firstTime = 1;
+ drawViewport(Xoption);
+ writeTitle();
+ sprintf(viewBitmapFilename,"%s%s%s",viewDirName,"/","image.bm");
+ code = XWriteBitmapFile(dsply,viewBitmapFilename,
+ viewport->titleWindow,vwInfo.width,
+ vwInfo.height+vwInfo.border_width+20,-1,-1);
+
+ writeImage = no;
+ break;
+
+ case Postscript:
+ /*** Create postscript output for viewport (in axiom3D.ps) ***/
+ sprintf(PSfilename,"%s%s",viewDirName,"/axiom3D.ps");
+ if (PSInit(viewport->viewWindow,viewport->titleWindow) == psError)
+ return(-1);
+ drawViewport(PSoption); /* write new script file in /tmp */
+ if (PSCreateFile(viewBorderWidth,viewport->viewWindow,
+ viewport->titleWindow, viewport->title) == psError)
+ return(-1); /* concat script & proc into axiom3D.ps */
+ break;
+ } /* switch on ii */
+ } /* if thingsToWrite >> ii */
+ } /* for ii */
+
+ return(0);
+ } /* else create directory okay */
+
+}
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}