Import Geant4 0.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-01 15:25:35 +02:00
parent 54d6b71f95
commit b97f8d0df7
3237 changed files with 807095 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
# $Id: GNUmakefile,v 2.2 1998/11/06 14:01:53 allison Exp $
# --------------------------------------------------------------
# GNUmakefile for graphics_reps library. John Allison, 19/7/96.
# --------------------------------------------------------------
name := G4graphics_reps
ifndef G4INSTALL
G4INSTALL = ../..
endif
include $(G4INSTALL)/config/architecture.gmk
CPPFLAGS += -I$(G4BASE)/global/management/include \
-I$(G4BASE)/global/HEPGeometry/include
include $(G4INSTALL)/config/common.gmk
.PHONY: global
global: lib
+101
View File
@@ -0,0 +1,101 @@
$Id: History,v 2.10 1998/12/02 14:28:44 evc Exp $
-------------------------------------------------------------------
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
Category History file
---------------------
This file should be used by G4 developers and category coordinators
to briefly summarize all major modifications introduced in the code
and keep track of all category-tags.
It DOES NOT substitute the CVS log-message one should put at every
committal in the CVS repository !
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
greps-00-04-02 02 December 1998 Evgeni Tcherniaev
- Added G4NURBS::CalcPoint() for calculation coordinates of a
point lying on the nurbs surface.
greps-00-04-01 25th November 1998 John Allison
- Added void G4VisAttributes::SetDaughtersInvisible (G4bool).
greps-00-03-03 9th November 1998 Satoshi Tanaka
Added G4String fInfo and its access functions to G4VMarker
greps-00-03-02 6th November 1998 John Allison
- Cleaned up GNUmakefile - no longer includes unnecesary -I's
greps-00-03-01 26th September 1998 John Allison
- Removed SetWorldVolume from G4VVisManager - no longer used.
greps-00-02-03 21st August 1998 John Allison
- Rationalised G4VisExtent::G4VisExtent (const G4Point3D& centre,
G4double radius) so that iit is a true "inverse" of GetExtentRadius.
- Added global target to GNUmakefile (Gabriele Cosmo).
greps-00-02-02 14th August 1998 John Allison
- Added GeometryHasChanged() to G4VVisManager. To be used by the run manager.
greps-00-02-01 6th August 1998 John Allison
- Removed Draw, ClearView and Show in G4VVisManager.
greps-00-06-03 26th June 1998 Gabriele Cosmo
- Updated test/GNUmakefile to new electromagnetics.
greps-00-06-02 10th June 1998 John Allison
- Changed defaults in G4VisExtent to 0.
1st June 1998 Satoshi Tanaka
- Added Draw(), ClearView(), Show() to G4VVisManager.
greps-00-06-01 29th April 1998 John Allison
- Introduced Establish/DecommissionSpecials (G4PhysicalVolumeModel&)
in place of BeginModeling (G4PhysicalVolumeModel&).
April 21st, 98 G.Cosmo (greps-00-05-03)
- Tagged.
April 9th, 98 G.Cosmo
- Porting on DEC-cxx 6.0.
Removed meaningless usage of "const" qualifier from functions
return type for basic types by value. Modified files: G4NURBS.cc
greps-00-05-02 4th April 1998 John Allison
- Re-engineered maintenance of current depth, etc. Needed new method
G4VGraphicsScene::BeginModeling (G4PhysicalVolumeModel&) in
graphics_reps. The result is much cleaner model and modeling
parameters classes. Also, the current depth, physical volume and
logical volume are immediately available as protected pointers in
G4VScene.
HEAD 3rd April 1998 John Allison
- Added GetWorld/ScreenDiameter/Radius to G4VMarker.
April 2, 1998 G.Barrand :
- G4Polyhedron.cc : add a G4double cast to help NT/Visual compiler.
greps-00-05-01 26th March 1998 John Allison
- Removed #if defined(__DECCXX) || defined(WIN32) from G4NURBS.hh.
- Improved comments in G4VMarker.hh
7th January 1998 John Allison
- Added arguments to PreAddThis in G4VGraphicsScene.hh.
- Added virtual destructor to G4VVisManager.
December 19, 97 G. Cosmo - (alpha03)
- Created.
- Previous history (from README)
vis-00-01-02 13th July 1997 John Allison
- Consolidation of previous tag.
vis-00-01-01 8th June 1997 John Allison
- First systematic tag.
- G4Polyhedron - can now set number of sides for circle polygon approximation
+3
View File
@@ -0,0 +1,3 @@
$Id: README,v 2.0 1998/07/02 17:29:42 gunter Exp $
FROM 1998, DETAILS ARE NOW IN History
+796
View File
@@ -0,0 +1,796 @@
$Id: G4NURBS.txt,v 2.0 1998/07/02 17:29:39 gunter Exp $
Olivier Crumeyrolle, 17th September 1996.
The G4NURBS C++ class library
Documentation (September 6 '96)
Introduction
In GEANT4, there is a need for visual representations. Non Uniform Rational
B-Spline (NURBS) are an interesting choice as they allow an exact
representation of conics, unlike others, and have a lot of other convenient
properties. Furthermore NURBS are an industry standard in Computer Aided
Design (CAD) systems.
The goal of the G4NURBS C++ class library is to handle NURBS and to provide all
the necessary methods so they can be succesfully used.
Summary
The G4NURBS class handles the data needed to define a NURBS surface,
i.e. the orders of the NURBS used, the knot values and control points
(explanations later).
G4NURBS provides an important number of access functions to allow any graphics
model (GM) to build its own NURBS. Although building the GM's NURBS with
G4NURBS data (or vice versa) without any copy would be the more efficient way,
different GMs typically use different data types, so copying and converting is
required. For that G4NURBS provides some basic functions and also some more
clever iterators to simplify the user's task.
Some GMs support NURBS (OpenGL, GPHIGS), but for others G4NURBS (will) provide
some adaptative tessellation functionalities, if possible as a convertion to
G4Polyhedron.
For the GEANT4 geometry user, G4NURBSbox, G4NURBScylinder, G4NURBStube and
G4NURBStubesector are implemented.
Some transformation functions (partial revolution in particular) will may be
added so anyone can build almost any shape with G4NURBS, starting with some
basic ones only, and without complication.
If everything's OK, G4NURBS could become a nice kind of primitive.
1 Building a G4NURBS instance
This section is essentialy dedicated to the GEANT4 geometry user.
1.1 From a G4VSolid to a G4NURBS
1.1.1 Box
It's straightforward with G4NURBSbox. If DX, DY and DZ are the half-lengths in
the X, Y an Z directions respectively, then
G4NURBSbox * pmybox = new
G4NURBSbox(DX, DY, DZ);
builds the corresponding box. Thanks to polymorphism,
this object is a G4NURBS like any other.
1.1.2 Tubs
In Geant4, tubs are used to represent some sectors of tube, but also complete
tubes and cylinders. To keep it simple, there is no G4NURBStubs, but a
G4NURBScylinder, a G4NURBStube and a G4NURBStubesector.
If RMIN, RMAX, DZ, PHI1, PHI2 are the tubs parameter (but with angles in
radians), then something like
G4NURBS * pmynurbs;
if (RMIN != 0)
{
if ( ((PHI2-PHI1) >= 2*M_PI) || (PHI2==PHI1) )
pmynurbs = new G4NURBStube(RMIN, RMAX, DZ);
else pmynurbs = new G4NURBStubesector(RMIN, RMAX, DZ, PHI1, PHI2);
}
else
{
if ( ((PHI2-PHI1) >= 2*M_PI) || (PHI2==PHI1) )
pmynurbs = new G4NURBScylinder(RMAX, DZ);
else pmynurbs = new G4NURBStubesector(0.0001, RMAX, DZ, PHI1, PHI2);
};
builds the appropriate representation.
NB: as you can see there is no sector of cylinder, so we use
G4NURBStubesector(epsilon, RMAX, DZ, PHI1, PHI2). A new release will include
G4NURBScylindersector one day.
Note that G4NURBStubesector can in principle handle all possible tubs, (it even
works with negative radius, negative length and more than two pi angle
difference) but the graphics system will probably have some difficulties with
the NURBS, and even if it display it, you will not like the result.
1.2 In general
One cannot build directly a G4NURBS object. G4NURBS is just an handling class.
To have some instance you must derive from G4NURBS and use one of its protected
constructors in the child class constructor initialisation list. The first
G4NURBS constructor is able to produce a regular knot vector for an unallocated
knot vector, and the second one (the most easy to use) handles allocation of
all arrays and is able to produce some "linear" but also some "circular" knots.
G4NURBSbox and G4NURBStube use the second constructor and are good examples,
G4NURBStubs is slightly more complex but shows how to build automatically a
G4NURBS. G4NURBScylinder is the only one written with the first constructor, to
provide an example. See also comments in G4NURBS.hh. This file contains in the
appendix an introduction to NURBS, with some examples. You should also follow
the recommendations in 4.2.4.
1.3 Future prospects
A child class with an istream based constructor might be written which allows
the user to load a NURBS Definition file (as the << overload currently
generates them).
Some transformation functions might be written in order to help the user to
build a NURBS from basic one. (suggestions are welcomed)
A child class G4NURBStrimmingcurve might be written with some methods to help
the user to clip NURBS or to convert some boolean solids into clipped NURBS.
However the GMs must support surface trimming, as it's not straightforward to
generate an equivalent representation of a trimmed NURBS (set of smaller NURBS?)
2 Access functions
This section will more interest the graphics model devloper.
2.1 Simple data access with and without a direction selector
To retrieve NURBS simple data (order, various numbers) a first set of
access functions is provided :
G4int getUorder() const;
G4int getVorder() const;
G4int getUnbrKnots() const;
G4int getVnbrKnots() const;
G4int getUnbrCtrlPts() const;
G4int getVnbrCtrlPts() const;
where nbr is short for number and CtrlPts for control points.
Another set of functions using a _selector_ is provided :
G4int getorder(t_direction in_dir) const;
G4int getnbrKnots(t_direction in_dir) const;
G4int getnbrCtrlPts(t_direction in_dir) const;
The selector in_dir is an enum in the G4NURBS scope. So the complete type name
is G4NURBS::t_direction, and values are G4NURBS::U for retrieving data related
to the U direction, and G4NURBS::V for V.
Hence the following calls are equivalent :
my_nurbs.getUorder();
my_nurbs.getorder(G4NURBS::U);
The first may be slightly faster than the second (cf inline code in G4NURBS.hh).
G4NURBS::NofD is also defined, where NofD means nbr of directions. One could use
it for loops over direction. However as enum can't be incremented this is not as
useful as it could be. See the << overload in G4NURBS.cc for a loop example or
the constuctors (still in G4NURBS.cc) for another example.
2.2 Access to knots and control points
2.2.1
A set of basic functions is provided :
G4float getfloatKnot( t_direction in_dir, t_indKnot in_index)
const;
G4double getdoubleKnot( t_direction in_dir, t_indKnot in_index)
const;
t_floatCtrlPt* getfloatCtrlPt( t_indCtrlPt in_onedimindex) const;
t_floatCtrlPt* getfloatCtrlPt( t_inddCtrlPt in_Uindex,
t_inddCtrlPt in_Vindex) const;
t_doubleCtrlPt* getdoubleCtrlPt(t_indCtrlPts in_onedimindex) const;
t_doubleCtrlPt* getdoubleCtrlPt(t_inddCtrlPts in_Uindex,
t_inddCtrlPts in_Vindex) const;
The first two return the in_index th knot (with a 0 based numbering, so the
valid index goes from 0 to nbrKnots-1) after converting it into G4float or
G4double. The four others functions do the same with control points. The
returned pointer points to a brand-new allocated array with the control points
coordinates. You can do what you want with it, it's _your_ copy, (non-const) and
you must delete it after use. You can give the U and V index or a global index,
as control points are stored U increasing first.
The followings calls are equivalent :
// suppose a 5 by 9 net of ctrlpts (5 along U, 9 along V)
// and t_doubleCtrlPt * pmycp;
pmycp = my_nurbs.getdoubleCtrlPt(3, 2);
pmycp = my_nurbs.getdoubleCtrlPt(13);
However, iterators are an easier way to retrieve the knots or the control points
in a sequential manner.
2.2.2 Iterators
Iterators are defined in the G4NURBS public scope, to avoid the global
namespace pollution. Therefore their type name is G4NURBS::KnotsIterator,
G4NURBS::CtrlPtsCoordsIterator, G4NURBS::CtrlPtsIterator.
Iterators are independent objects : you can allocate as many iterators as you
want and make them work concurrently. However the G4NURBS object MUST be defined
when you use iterators over it (and must not be changed). See the Possible
improvements 1.2 section for more about that.
2.2.2.1
G4NURBS::KnotsIterator allows the user to retrieve knots one after the other. It
can be used as follows to get all the knots along the U direction as 'float'
numbers :
// assuming mynurb is a G4NURBS, for instance G4NURBSbox my_nurb(1,2,3);
G4float * my_array, * my_float_p;
my_float_p = my_array = new float [my_nurb.getnbrKnots(G4NURBS::U)];
G4NURBS::KnotsIterator my_iterator(my_nurb, G4NURBS::U);
while (my_iterator.pick(my_float_p++));
Then my_array contain all the knots, and my_float_p point just after the array.
The trick is that pick functions return false when they pick the last knot.
The constructor has an optional third argument, in_startIndex, preseted to zero.
It's possible to give another value to retrieve half of the knots for instance.
(will probably be used in splitting)
2.2.2.2
G4NURBS::CtrlPtsCoordsIterator is very similar to the Knots one.
The control points are retrieved coordinate after coordinate,
and, if we note i the index along U and j the one along V,
control points P_i_j themselves are obtained i increasing first, j after :
P_1_1, P_2_1, P_3_1, P_4_1, ....., P_1_2, P_2_2, P_3_2, P_4_2, ....
G4float * my_array, * my_float_p;
my_float_p = my_array = new float [my_nurb.gettotalnbrCtrlPts()
*G4NURBS::NofC*sizeof(float)];
G4NURBS::CtrlPtsCoordsIterator my_iterator(my_nurb);
while (my_iterator.pick(my_float_p++));
2.2.2.3
G4NURBS::CtrlPtsIterator work control point by control point, instead of control
point coordinate by control point coordinate. Remember that control points are
given U index increasing first, V after. The << overload in G4NURBS.cc contains
an exemple where the retrieved control point is used immediately.
2.2.3
Some "complete-copy" functions are also provided.
G4float * getfloatAllKnots(t_direction in_dir) const;
G4double * getdoubleAllKnots(t_direction in_dir) const;
G4float * getfloatAllCtrlPts() const;
G4double * getdoubleAllCtrlPts() const;
These functions return a pointer over a new array with all the knots or control
points copied. You do not control the allocation nor the copy, but you own the
result and will have to delete it.
They are more easy to use than iterators, but less flexible.
Be careful with these functions, as _you_ choose the type, whereas with
iterators the compiler choose the good pick function for you. If G4double or
G4float change, you must change your code, instead of just recompile it.
3 Use in GEANT4
3.1 NURBS manipulations
The public interface of G4NURBS does not allow the user to modify a NURBS. The
user is expected to create G4NURBS via child classes. Splitting, tesslation, or
other non-conservative processes should occur only as a conversion to a child
class, via its constructor, or eventually with a conversion operator.
e.g.
G4NURBSashape mynurbs(foo, goo, hoo);
// for splitting
G4NURBSsplit mypieceofnurbs(mynurbs, splitdirection, splitpointvalue);
// for tessellation, if
// class G4PolyhedronedNURBS : public G4Polyhedron
// has a constructor G4PolyhedronedNURBS(const G4NURBS &, G4Float tolerance)
G4PolyhedronedNURBS mytessellatednurbs(mynurbs, thetolerance);
// (a multiple inheritance could be used to have a "dual-face"
// object Polyhedron/NURBS, with the advantage of keeping
// a NURBS and its tessellation together, and the disadvantge
// of duplicating the original NURBS into this child)
The resulting instance is not necessary constant, G4NURBSsplit could provide
some sub-splitting and refinement methods that act on itself.
3.2 Copying policy
A copy constructor is provided, but in the private part. A warning message
( "WARNING: G4NURBS::G4NURBS(const G4NURBS &) used" )
is printed on cerr each time the copy constructor is called.
As long as there is no sophisticated memory management scheme that reduce
useless duplications, copying should be avoided. We have already to duplicate
data for the GM, once is enough.
4 Possible internal improvements that could have consequences
4.1 Memory management :
4.1.1 G4NURBS use the minimal memory management scheme possible. Control
points, knots, are stored in basic arrays. NURBS characteristics are
stored in simple structure. All those internal data could be handled in
protected classes with ad hoc constructors, which would be more
reliable. The G4NURBS copy constructor would be more elegant. However
performance may decrease. This point is related to typing. See 2.1.
4.1.2 Some reference counting facilities should be added for internal arrays
so that iterators could correctly work after a G4NURBS is
deleted/changed. This point could be solved with 1.1 in a elegant way.
We should at least warn the user when a nurbs is deleted before the
corresponding iterators. However if we want to do the things in a good
way references counters must be associated to arrays. Once again 1.1 is
the solution for that. To put references as members, we need the future
"mutable" keyword planed by the ANSI C++ committee, or the counting will
be uncompatible with const instances.
4.2 Internal data type
4.2.1 Knots and control points types are just typedefs, idem for index types.
They could be strong types (i.e. classes), but performance costs will
may be significant.
4.2.2 enum type are useful to enforce the user to do good things (like using
G4NURBS::U instead of 0), but are not really convenient for loops. Some
internal alias should be defined to allow some more easy loops. [this
concern the geom user only if he/she writes some G4NURBS children]
4.2.3 As the user doesn't know the internal data type, it could be possible
for G4NURBS to adapt itself to the GM currently used, so this GM could
use directly the G4NURBS data. This adaptation concern the control
points storage order and knot values (some fast algorithms exists for
knots which differe of 0 or 1 only). It would be necessary to write some
inline functions for control points initialization that spare the child
class writer to know the storage order, see 4.2.4. But once again, what
about performance ? The G4NURBS constructors and the initializations
functions used in child constructors would have to change their target
type, and thus we need a very clever scheme to be compatible with the
use of different GMs in the same time.
4.2.4 For the momment the control points storage order is publicly known, that
could change, with a formal class level between G4NURBS and
G4NURBSashape children. Calls like CP(mpCtrlPts[..], .... will have to
be rewritten; a tool will may be provided to automaticaly do that. Use
if possible explicit U & V index values like
CP(mpCtrlPts[to1d(U_index, V_index)], .......
[this concerns the geometry user only if he/she writes some
G4NURBSashape].
4.3 External interfacing types
4.3.1 For the moment G4int, G4double, G4float, are just alias for int, double,
float. These G4 types are used in the G4NURBS interface (the public part
of G4NURBS). If their definitions are changed, the significance of the
access functions will change too, user should take care about that when
using access functions with some others types (e.g. GLfloat ) In a more
general way this type interfacing problem will have to be solved at a
general level as different GS are used. For the moment G4Float is used
internally and interfaced to G4float and G4double.
4.3.2 Child constructors take all their arguments as G4double. This may have
to change, depending on the exact work that G4VSolid children have to
do. Length arguments should be unsigned (but unsigned G4double is
illegal), and angles in radians should have a different type from those
in degrees.
4.4 Names
4.4.1 G4NURBS could become G4VNurbs, and G4NURBSbox could become G4NurbsBox.
5 Prospects
5.1 For NURBS in general
NURBS are likely to become more and more widely supported by software, but also
by hardware. Nvidia NV1 PCI card for PCs already accelerate quadratic curves
(and may be more) . The new SPARCstation 20TurboZX provide dynamic tessellation
for NURBS in firmware.
5.2 Births
G4NURBS will probably have others children in the future, in particular for
splitting. However the object oriented programming allows anyone to create some
child classes. Don't hesitate to enlarge the family.
Appendix
Non Uniform Rational B-Spline (NURBS).
1 About Representation
A curve or a surface are mathematicaly a set of points. However the number of
points is infinite, what is not convenient at all. We need a more operational
way for describing the set of points. Here we use a parametric representation :
the curve is described by a function of 1 real parameter t : C(t), the surface
with two parameters called u and v : S(u,v). As the parameter(s) go(es) from a
minimal value to a maximal one, the function describes the curve/surface. Now we
need a representation for this function itself. To achieve this, the function is
projected over a set of basis functions. Of course the kind of functions we can
represent in this way is determined by the kind of basis functions used. We will
work with real-valued polynomial function, as they are easy to represent, can
approximate any continuous function as well as we want and are convenient in
general. Once basis functions are chosen, the kind of 'coordinates' that a
function will have over such a basis is determined : the function describe a set
of point whereas basis functions chosen are real-valued, so the 'coordinates'
are necessary some points, called control points, noted P_i (or P_{i,j}),
represented by their position-vector, and multipied by the basis functions.
A curve will then be expressed as C(t) = sum(i = 1, n) { P_i * B_i(t) }
where B_i is the ith basis functions.
A surface could be expressed as S(u,v) = sum(i = 1, n) { P_i * B_i(u,v) },
but we will use a more easy scheme, explained in 2.5
An interesting point is that if T is a linear transformation,
T[C(t)] = sum(i = 1, n) { T[P_i] * B_i(t) }
2 B-Spline curves and surfaces
2.1 B-Spline basis functions
They are defined as following :
B_{i,1} = 1 if t_i <= t <= t_{i+1}, 0 otherwise
B_{i,k}(t) = ((t-t_i)/(t_{i+k-1}-t_i))*B_{i,k-1}(t)
+
((t_{i+k}-t)/(t_{i+k}-t_{i+1}))*B_{i+1,k-1}
i goes from 1 to n, the number of basis functions.
k is the order of the B-Spline.
(t_i)_{1<=i<=n+k} a sequence of non-decreasing values called knots that defines
the B_{i,k}, and is globaly designed as the knot vector.
The B-Spline is said to be uniform if t_{i+1}-t_i = d > 0 for any i, non-uniform
(NU) otherwise, with the convention 0/0 = 0.
We concentrate first on uniform B-Splines (UBS)
2.2 Some UBS properties
The recursive relation defines B_{i,k} as a linear interpolation between
B_{i,k-1} and B_{i+1,k-1}. Thus B_{i,k} is a polynomial of degree k-1,
strictly positive in [t_i, t_{i+k}], nul elsewhere. For a given t / t_i <= t <
t_{i+1}, only B_{i-k+1,k} to B_{i,k} are non-nul. The (endknot-startknot)
divisors in the relation imply that sum(i = 1,n){B_{i,k}(t)} = 1.
[picture of UBS basis functions from k=1 to 2 or 3]
2.3 Change of basis : the Oslo algorithm
It is possible to increase the number of basis functions used.
If (t_i)_{1<=i<=n+k} is the old knot vector and (t'_i)_{1<=i<=n'+k} the new
one, then P'_i = sum (j = 1, n) { alpha_{i,j,k} * P_j }
where alpha_{i,j,k} is given by a recursive relations similar to B_i,k ones :
alpha_{i,j,k} = ((t'_{j+k-1} - t_i) / (t_{i+k-1} - t_i)) * alpha_{i,j,k-1}
+ ((t_{i+k} - t'_{j+k-1}) / (t_{i+k} - t_{i+1})) * alpha_{i+1,j,k-1}
The Oslo algorithm is not used in the G4NURBS class library at the moment,
but it will when splitting functionalities will be added.
2.4 UBS curves
Once we have defined the basis function, a curve is expressed as following :
C(t) = sum(i = 1, n) { P_i * B_{i,k}(t) }
where P_i are the control points and k the order.
(This maps [t_min, t_max] to the curve.)
If we note C^n the class of functions that are continuous up to the nth
derivative (included), then for t_i < t < t_{i+1}, C(t) is C^infinite, and at t
= t_i, C(t) is C^{k-2}.
[pictures ?]
If a control points is repeated k-1 time or more, the curve goes through it.
2.5 UBS surfaces
Surfaces are expressed as the tensor product of two curves :
S(u,v) = sum(i=1,n) sum(j=1,m) { P_{i,j}*B_{i,k}(u)*B_{j,l}(v) }
where P_{i,j} is the net of control points.
(This maps [u_min,u_max] x [v_min,v_max] to the surface.)
This is more convenient than starting from 2D splines, or similar functions,
but you must keep in mind that with such a scheme the curve along one direction
must be sufficently complexe to handle the shape complexity all along this
direction. However it's sometime possible to choose a direction for a parameter
in such a way that the surface is more simple along this direction.
2.6 Choice of parameter domain
In the G4NURBS class library, the default is zero as the minimal parameter
value, one for the maximal, and t_{i+1}-t_i = ( 0 or constant) ). However
examples in section 4 will use t_i = integer for non-coincident knots, as it's
more legible.
3 NURBS curves and surfaces
3.1 NU
As previously said, the knots interval can vary. As we still impose t_{i+1} >=
t_i, the limit case is t_{i+1} = t_i. In such a case, B_{i,1} is reduced to a
point, B_{i,2} and B_{i+1,2} overlap on a knot segment reduced to a point, and
at this point C(t) will be only C^{k-3}, making the curve less smooth. More
generally if a knot appears M times, C(t) is C^{k-M-1}. If M = k-1, C(t) is
C^0, the curve is still continuous but can have a corner at t = t_i = ... =
t_{i+k-2} and go through the corresponding control point P_{i-1}, thanks to
B_{i-1,k} that cover t_i to t_{i+k-2,k}. If M = k, the curve is no longer
continous : all the basis B-Splines from B_{i-k,k} to B_{i-1,k} stop at t = t_i
= ... = t_{i+k-1} and the curve stop a the corresponding control point
P_{i-1}. If there are other knots and control points after, the curve restarts
from next control point P_i, as B_{i,k} to B_{i+k-1,k} start at t_{i+k-1} = t'.
3.2 R
The control points are no longer usual position vectors in the plane
(isomorphic with R^2) or in the space (isomorphic with R^3) but an element of
the projective space P^n, which as one dimension more that the corresponding
usual space. P^n, isomorphic with R^n, is associated with the usual space
isomorphic with R^{n-1} : (x, y, w) in P^3 corresponds to (x/w, y/w) in R^2,
(x, y, z, w) in P^4 corresponds to (x/w, y/w, z/w) in R^3 and so on. If w = 0,
the point goes to infinity, defining a direction. Thus working in the
projective space allows us to work with points and vectors, and all affine
transformations in the usual space can be combined into a linear ones in the
projective space, as well as projections. The coordinates in P^n are said to be
homogeneous or rational, and items expressed with such coordinates are
highlighted by an ^h.
3.3 NU R BS
NURBS are NUBS in the projective space. Hence to transform a NURBS, one just
has to transform the control points, even for projections.
The last homogeneous coordinate w is called the "weight".
3.4 NURBS curves
If P_i = (x_i, y_i), then P^h_i = (w_i*x_i, w_i*y_i, w_i)
and a curve is expressed in P^3 by
C^h(t) = sum(i = 1, n) { P^h_i * B_{i,k}(t) }
and in R^2 by
C(t) = sum(i = 1, n){ w_i* P_i * B_{i,k}(t) } / sum(i = 1, n){ w_i* B_{i,k}(t) }
3.5 NURBS surfaces
If P_i = (x_i, y_i, z_i), then P^h_i = (w_i*x_i, w_i*y_i, w_i*z_i, w_i)
and a surface is expressed in P^4 by
S^h(u,v) = sum(i=1,n) sum(j=1,m) { P^h_{i,j} * B_{i,k}(u) * B_{j,l}(v) }
and in R^3 by
S(u,v) = sum(i=1,n) sum(j=1,m) { w_{i,j} * P_{i,j} * B_{i,k}(u) * B_{j,l}(v) }
/sum(i=1,n) sum(j=1,m) { w_{i,j} * B_{i,k}(u) * B_{j,l}(v) }
3.6 NURBS advantages/disadvantages
3.6.1 Advantages :
Common representation for shapes, even with discontinuities.
Exact representation of conics section (and for all shapes that have a
polynomial parametrisation in the projective space).
Invariant under affine and perspective tranformations.
Flexible (lot of manipulations possible, cf 4).
Generalization of others B-splines / Bezier shapes.
3.6.2 Drawbacks :
Today need some calculations to be converted to triangles and/or
quadrilaterals as these are the only kind of shapes directly handled
by graphics systems at low-level (OpenGL is able to do that but it
really generate too many triangles/squares).
Extra storage for simple shapes.
We must choose a good parameterisation.
4 Examples of NURBS
4.1 Linear
With 2.1 definition, linear B-Spline are order 2 : k = 2.
All the weigths are equal to ones in what follows.
4.1.1 Segment
We want a strait line from P_1 to P_2. To start the curve at P_1, we need a knot
repeated k times at the begining and at the end of the knot vector. Thus the
knot vector looks like { 0 0 ... 1 1 }. Do we need more than four knots ? No,
two control points, a second order NURBS, 2 + 2 = 4, number of knots. (Remember
(t_i)_{1<=i<=n+k})
4.1.2 Polyline
We could just put some lines in such a way that they connect each other in a
head to tail fashion,
{ 0 0 1 1 }
[ P_1, P_2 ]
Set P_3 = P_2
{ 0 0 1 1 }
[ P_3, P_4 ]
Set P_5 = P_4
{ 0 0 1 1 }
[ P_5, P_6 ]
and union them in one NURBS :
{ 0 0 1 1 2 2 3 3 }
[ P_1, P_2, P_3, P_4, P_5, P_6 ] still with P_3 = P_2 and P_5 = P_4.
Then we can simplify the NURBS :
{ 0 0 1 2 3 3 }
[ P_1, P_3, P_4, P_6 ]
4.1.3 Square
If P_1, P_2, P_3, P_4 are the four corners, we can do a NURBS with
a polyline that starts and stop at P_1 :
{ 0 0 1 2 3 4 4 }
[ P_1 P_2 P_3 P_4 P_1 ]
4.1.4 Box
If we take a square and move it (=extrude) along a perpendicular edge, we get a
box which lack to faces, the two ones that are perpendicular to the edge along
which we extruded the square. Note that if you change the order in which you are
considering the tensor product, this surface is a segment (the edge) moved along
a square.
{ 0 0 1 2 3 4 4 } by
[ P_1 P_2 P_3 P_4 P_1 ] { 0 0
[ P'_1 P'_2 P'_3 P'_4 P'_1 ] 1 1 }
To close the sides, we repeat the extremeties,
{ 0 0 1 2 3 4 4 } by
[ P_1 P_2 P_3 P_4 P_1 ] { 0 0
[ P_1 P_2 P_3 P_4 P_1 ] 1
[ P'_1 P'_2 P'_3 P'_4 P'_1 ] 2
[ P'_1 P'_2 P'_3 P'_4 P'_1 ] 3 3 }
and then reduce the first and last square to a line or a point.
For instance if P_0 is the center of the P_i side and P'_0 the one of the P'_i,
{ 0 0 1 2 3 4 4 } by
[ P_0 P_0 P_0 P_0 P_0 ] { 0 0
[ P_1 P_2 P_3 P_4 P_1 ] 1
[ P'_1 P'_2 P'_3 P'_4 P'_1 ] 2
[ P'_0 P'_0 P'_0 P'_0 P'_0 ] 3 3 }
(Put differently, we take half of a rectangle and "rotate" it along a square.)
The G4NURBSbox use something like
{ 0 0 1 2 3 4 4 } by
[ P_1 P_1 P_4 P_4 P_1 ] { 0 0
[ P_1 P_2 P_3 P_4 P_1 ] 1
[ P'_1 P'_2 P'_3 P'_4 P'_1 ] 2
[ P'_1 P'_1 P'_4 P'_4 P'_1 ] 3 3 }
rectangles reduced to lines, to avoid a "star" effect on display.
4.1.4 Trap
There is no realy difference with the box. One just have to check
that P_i and P'_i are on the same edge, or the trap will be twisted.
4.2 Quadratic :
Quadratic B-Splines are order 3 : k = 3.
4.2.1 Arc
We start at P_1 = (1,0) in R^2, and stop at P_3 = ( cos phi, sin phi ).
With the knot vector { 0 0 0 1 1 1 }, we just need another control point, P_2.
P_2 defines with P_1 the tangent at P_1, and with P_2 the tangent at P_2,
thus P_2 is at ( 1, tan phi/2 ) and its weight is not 1, unlike P_1 and P_3,
but cos phi/2.
4.2.2 Circle
To avoid infinite values, a circle is made by many arcs, for instance
three 120 degrees arcs or four 90 degrees arcs. They are joined and simplified
as for the polyline.
ex:
the circle used in G4NURBScylinder is made by four 90 degree arc :
(s = sqrt(2)/2)
{ 0 0 0 1 1 2 2 3 3 4 4 4 }
[ 1,0,1 s,s,s 0,1,1 -s,s,s -1,0,1 -s,-s,s -1,0,1 -s,s,s 1,0,1 ]
4.2.3 Cylinder
We build a cylinder from the circle as we made the box from the square :
extrusion + closing
4.2.3 Tube
The tube is obtained by revolving a rectangle around the tube axis.
For suggestion/change/English corrections : contact me or e-mail (via
olivierc@h2.ph.man.ac.uk)
( I'm sure it needs some English corrections )
+28
View File
@@ -0,0 +1,28 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Circle.hh,v 2.0 1998/07/02 17:30:39 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 17/11/96.
#ifndef G4CIRCLE_HH
#define G4CIRCLE_HH
#include "G4VMarker.hh"
class G4Circle: public G4VMarker {
public:
G4Circle ();
G4Circle (const G4Point3D& pos);
G4Circle (const G4VMarker& marker);
};
#include "G4Circle.icc"
#endif
+20
View File
@@ -0,0 +1,20 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Circle.icc,v 2.0 1998/07/02 17:29:43 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 17/11/96.
inline G4Circle::G4Circle () {}
inline G4Circle::G4Circle (const G4Point3D& pos):
G4VMarker (pos) {}
inline G4Circle::G4Circle (const G4VMarker& marker):
G4VMarker (marker) {}
+21
View File
@@ -0,0 +1,21 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Color.hh,v 2.0 1998/07/02 17:29:50 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 20th October 1996
#ifndef G4COLOR_HH
#define G4COLOR_HH
#include "G4Colour.hh"
typedef G4Colour G4Color;
#endif
+48
View File
@@ -0,0 +1,48 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Colour.hh,v 2.0 1998/07/02 17:29:51 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 20th October 1996
#ifndef G4COLOUR_HH
#define G4COLOUR_HH
#include "globals.hh"
class ostream;
class G4Colour {
friend ostream& operator << (ostream& os, const G4Colour& c);
friend G4bool operator != (const G4Colour& c1, const G4Colour& c2);
public:
G4Colour (G4double r = 1., G4double g = 1., G4double b = 1.,
G4double a = 1.);
G4double GetRed () const;
G4double GetGreen () const;
G4double GetBlue () const;
G4double GetAlpha () const; // alpha = opacity = 1. - transparency.
private:
G4double red, green, blue, alpha;
};
inline G4Colour::G4Colour (G4double r, G4double g, G4double b, G4double a):
red (r), green (g), blue (b), alpha (a)
{
if( red > 1.0 ){red = 1.0;} if( red < 0.0 ){red = 0.0;}
if( green > 1.0 ){green = 1.0;} if( green < 0.0 ){green = 0.0;}
if( blue > 1.0 ){blue = 1.0;} if( blue < 0.0 ){blue = 0.0;}
if( alpha > 1.0 ){alpha = 1.0;} if( alpha < 0.0 ){alpha = 0.0;}
}
inline G4double G4Colour::GetRed () const {return red;}
inline G4double G4Colour::GetGreen () const {return green;}
inline G4double G4Colour::GetBlue () const {return blue;}
inline G4double G4Colour::GetAlpha () const {return alpha;}
#endif
+504
View File
@@ -0,0 +1,504 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4NURBS.hh,v 2.3 1998/12/01 13:37:14 evc Exp $
// GEANT4 tag $Name: geant4-00 $
//
// Olivier Crumeyrolle 12 September 1996
// G4NURBS.hh
// prototype for class G4NURBS - see documentation in graphics_reps/doc.
// OC 280896
#ifndef __C_G4NURBS__
#define __C_G4NURBS__ 1
#include "globals.hh"
#include "G4VVisPrim.hh"
// HP's CC compiler :
// it's recommended that you include G4NURBS.hh BEFORE any other includes,
// at least before iostream.h
// checked for CC, xlC, g++, cxx
// * a friendness problem with DEC's cxx, fixed by __C_G4NURBS_FFIX__ *
//#if defined(__DECCXX) || defined(WIN32) i.e., always defined.
#define __C_G4NURBS_FFIX__ 1
//#endif
// The internal floating point type is G4Float, defined line 162
#include "G4ios.hh"
#include "G4Point3D.hh"
#include "G4Vector3D.hh"
class G4NURBS : public G4VVisPrim {
public:
// NO public constructor. A G4NURBS must be builded with a child class.
// Pure virtual function Whoami so one can't instanciate G4NURBS at all.
// Whoami return a string describing the NURBS (e.g "Box")
// * this string must not contain any \n *
// this string is *not* yours (const char)
virtual const char* Whoami() const = 0;
// the copy constructor is private.
// destructor.
virtual ~G4NURBS();
// direction selector defined as a type because the user will use it
// and we want the user to be well-manered.
// However internally this typed enum is not as easy to use as it
// could be (we can't ++). "t_" means it's a kind of local type.
enum t_direction {
U = 0,
V = 1,
DMask = 1, // NofD : Number of Directions
NofD = 2 // DMask : direction mask for fast range control,
}; // e.g. : m[a_dir & DMask]
// external representation for t_direction (just U -> 'U' V -> 'V')
static char Tochar(t_direction in_dir);
// mother index type (I'd like to be able to use unsigned G4int
// but it's impossible)
typedef unsigned int t_index;
// type for knot index, derivate from t_index
typedef t_index t_indKnot;
// type for ctrlpt coord and ctrlpt index
typedef unsigned int t_indCoord;
typedef unsigned int t_indCtrlPt; // mono index
typedef t_index t_inddCtrlPt; // bi dim index, derivate from t_index
// why only t_inddCtrlPt and t_indKnot (and t_order further)
// "derive" of t_index ? Because only these ones need
// to be compatible (order + nbrctrlpts = nbrknots in a given direction)
// Ok, typedefs are not true type derivation,
// but this is the "spirit" of declarations with t_index.
// To do true derivation we need true classes
// but classes for int are wastefull with today's compilers.
// Note that these index types are defined
// without knowledge of the indexed items types and that's perfect.
// interface data type for the rationnal control points
enum { X, Y, Z, W, NofC }; // NofC : number of coordinates
// not typed as t_indCoord so loops are easy
// to write, but the user is less restricted
typedef G4double t_doubleCtrlPt [NofC]; // with doubles
typedef G4float t_floatCtrlPt [NofC]; // with floats
// access functions for others (e.g. GraphicsModel)
G4int GetUorder() const;
G4int GetVorder() const;
G4int GetUnbrKnots() const;
G4int GetVnbrKnots() const;
G4int GetUnbrCtrlPts() const;
G4int GetVnbrCtrlPts() const;
G4int GettotalnbrCtrlPts() const;
G4double GetUmin() const;
G4double GetUmax() const;
G4double GetVmin() const;
G4double GetVmax() const;
void CalcPoint(G4double u, G4double v,
G4Point3D &p, G4Vector3D &utan, G4Vector3D &vtan) const;
// alternate access functions with G4NURBS::t_direction
// e.g. mynurb.Getorder(G4NURBS::U)
// these functions never fail because in_dir is masked
G4int Getorder(t_direction in_dir) const;
G4int GetnbrKnots(t_direction in_dir) const;
G4int GetnbrCtrlPts(t_direction in_dir) const;
// crude access to knots vector and control points.
// float and double versions.
// * one should rather use the iterators below *
// get a *copy* of the value; this copy is the user's
// one, so the user is intended to manage it (including delete).
// in_dir is masked, in_index checked and rounded.
// errors on G4cerr
G4float GetfloatKnot(t_direction in_dir, t_indKnot in_index) const;
G4double GetdoubleKnot(t_direction in_dir, t_indKnot in_index) const;
t_floatCtrlPt* GetfloatCtrlPt(t_indCtrlPt in_onedimindex) const;
t_floatCtrlPt* GetfloatCtrlPt(t_inddCtrlPt in_Uindex, t_inddCtrlPt in_Vindex) const;
t_doubleCtrlPt* GetdoubleCtrlPt(t_indCtrlPt in_onedimindex) const;
t_doubleCtrlPt* GetdoubleCtrlPt(t_inddCtrlPt in_Uindex, t_inddCtrlPt in_Vindex) const;
// complete copy functions
// the user don't control the allocation and the copy process
// but he/she own the result and will have to delete it
// when he/she does not need it any more.
G4float* GetfloatAllKnots(t_direction in_dir) const;
G4double* GetdoubleAllKnots(t_direction in_dir) const;
G4float* GetfloatAllCtrlPts() const;
G4double* GetdoubleAllCtrlPts() const;
// the iterators need that, the user does not
protected:
// internal type for reel numbers
// ( Float is defined in templates.hh and is
// under the control of HIGH_PRECISION )
typedef Float G4Float;
// internal type for order, derivate from t_index
typedef t_index t_order;
// internal type for knot
typedef G4Float t_Knot;
// internal types for the control points
typedef G4Float t_Coord;
typedef t_Coord t_CtrlPt [NofC];
// (nb: templates.hh included in globals.hh)
// type for ref counting
//typedef unsigned int t_refcount;
public:
// iterators for an .... iterative access to knots and control points
// errors are reported on G4cerr
// they are friends, they use the protected members.
// one can have as many iterators as he/she wants working in the same time.
// declarations of iterators
class KnotsIterator;
class CtrlPtsCoordsIterator;
class CtrlPtsIterator;
// friendness declarations for iterators
friend class KnotsIterator;
friend class CtrlPtsCoordsIterator;
friend class CtrlPtsIterator;
// Example for the KnotsIterator
// G4float * my_array, * my_float_p;
// my_float_p = my_array = new float [my_nurb.GetnbrKnots(G4NURBS::U)];
// G4NURBS::KnotsIterator my_iterator(my_nurb, G4NURBS::U);
// while (my_iterator.pick(my_float_p++));
// that's all! my_array contain all the U knots.
class KnotsIterator {
public:
KnotsIterator(const G4NURBS & in_rNurb, t_direction in_dir, t_indKnot in_startIndex = 0);
G4bool pick(G4double * inout_pDbl);
G4bool pick(G4float * inout_pFlt);
//~KnotsIterator();
protected:
const t_direction kmdir;
const t_Knot * const kmpMax;
const t_Knot * mp;
};
// the CtrlPtsCoordsIterator. Works like the knots' one :
// G4float * my_array, * my_float_p;
// my_float_p = my_array = new float [my_nurb.GettotalnbrCtrlPts()*G4NURBS::NofC*sizeof(float)];
// G4NURBS::CtrlPtsCoordsIterator my_iterator(my_nurb);
// while (my_iterator.pick(my_float_p++));
// after the while statement; my_float_p point just after the array
// Remember ctrlpts are given U index increasing first
class CtrlPtsCoordsIterator {
public:
CtrlPtsCoordsIterator(const G4NURBS & in_rNurb, t_indCtrlPt in_startCtrlPtIndex = 0);
G4bool pick(G4double * inout_pDbl);
G4bool pick(G4float * inout_pFlt);
//~CtrlPtsCoordsIterator();
protected:
const t_Coord * const kmpMax;
const t_Coord * mp;
};
// this iterator work CtrlPt by CtrlPt
// see the << overload for an example
class CtrlPtsIterator {
public:
CtrlPtsIterator(const G4NURBS & in_rNurb, t_indCtrlPt in_startIndex = 0);
G4bool pick(t_doubleCtrlPt * inout_pDblCtrlPt);
G4bool pick(t_floatCtrlPt * inout_pFltCtrlPt);
//~CtrlPtsIterator();
protected:
const t_CtrlPt * const kmpMax;
const t_CtrlPt * mp;
};
// Q: a directional Iterator to extract one col/row of CtrlPts ?
protected:
// little structure containing data for each direction
class t_Dir;
friend class t_Dir;
class t_Dir {
public:
t_order order;
t_inddCtrlPt nbrCtrlPts;
t_indKnot nbrKnots;
t_Knot * pKnots;
//t_refcount nbralias;
};
// check flag for the constructor
typedef enum { NOcheck, check } t_CheckFlag;
// first constructor (see G4NURBScylinder.cc for an example)
// compulsory arguments :
// order of the surface in U and V direction
// number of control points in U and V direction
// control points array (usualy empty here, *but* allocated)
// optional arguments :
// U and V knots vector (can be automaticaly generated)
// check flag (default is to check!)
//
G4NURBS (t_order in_Uorder, t_order in_Vorder,
t_inddCtrlPt in_UnbrCtrlPts, t_inddCtrlPt in_VnbrCtrlPts,
t_CtrlPt * in_pCtrlPts,
t_Knot * in_pUKnots = NULL, t_Knot * in_pVKnots = NULL,
t_CheckFlag in_CheckFlag = check );
// NB: the minimal NURBS is order 1, 2 knots, => 1 control points
// one can actually define some curves with G4NURBS, set U as you want
// set the V dir as order 1, 1 ctrlpt, 2 knots { 0 1 }
// OpenGL work with this kind of data
// second constructor (easier to use) (see G4NURBStube.cc for an example)
// compulsory arguments :
// order of the surface in U and V direction
// number of control points in U and V direction
// optional arguments :
// U and V knots vector generation flag (automaticaly or not)
// check flag (default is to check!)
// Allocations are Done for the user
// but he/she still have to fill some arrays
// For the moment I don't see yet how to ensure
// that the user correctly fill the arrays
// (in particular how avoid out of range access)
// without class types for arrays.
#ifdef __C_G4NURBS_FFIX__
public:
#endif
// knots vector generation flag
enum t_KnotVectorGenFlag {
UserDefined, // The user will fill the array (in the child constructor for instance).
Regular, // First and last knot repeated order time
// other knots regularly spaced, unrepeated.
// Typically used for "linear" knots vector
RegularRep // First and last knot repeated order time
// other knots regularly spaced but repeated one time.
// Typically used for "circular" knots vector and alikes.
}; //t_KnotVectorGenFlag
#ifdef __C_G4NURBS_FFIX__
protected:
#endif
// external representation for t_KnotVectorGenFlag
// as a << overload.
// (used in errors report)
friend ostream & operator << (ostream & inout_OutStream,
t_KnotVectorGenFlag in_KVGFlag);
G4NURBS (t_order in_Uorder, t_order in_Vorder,
t_inddCtrlPt in_UnbrCtrlPts, t_inddCtrlPt in_VnbrCtrlPts,
t_KnotVectorGenFlag in_UKVGFlag = Regular,
t_KnotVectorGenFlag in_VKVGFlag = Regular,
t_CheckFlag in_CheckFlag = check );
// nurbs data
t_Dir m[NofD]; // t_Dir : order nbrCtrlPts nbrKnots pKnots
t_indCtrlPt mtotnbrCtrlPts; // Total number of control points
t_CtrlPt * mpCtrlPts; // U increasing first, V after
//t_refcount mnbralias; // ref count for mpCtrlPts
// 2dim index to 1 dim conversion
t_indCtrlPt To1d(t_inddCtrlPt in_Uindex, t_inddCtrlPt in_Vindex) const;
// internal functions for converting the internal
// data points to the interface type required
// one can do some better things with class conversion
// but for the moment control point data types are not class.
// static functions.
// if changed to member functions, one must add the const
// status and rewrite calls with an instance in
// some of the get functions.
// return a float copy
static t_floatCtrlPt* TofloatCtrlPt(const t_CtrlPt &);
// return a double copy
static t_doubleCtrlPt* TodoubleCtrlPt(const t_CtrlPt &);
// Building functions
// KnotsVector builder
// static function that work on a t_Dir and its
// knot vector. So we can define
// some knots vector outside a nurbs
// object. (This avoid the existence
// of some incompletly defined nurbs object,
// used just as knots vector container)
// Return true if succesfull.
// ALWAYS allocate the knots array.
// (return false and do nothing if it already exists (ie != NULL))
// Always fail if order + nbrCtrlPt != nbrKnots
static G4bool MakeKnotVector(t_Dir & inout_dirdat, t_KnotVectorGenFlag in_KVGFlag);
static G4bool MakeKnotVector(t_Dir * p_inoutdirdat, t_KnotVectorGenFlag in_KVGFlag);
// the second is just an alias, cf further
// others building functions ?
// revolve ?
// partial revolve ?
static void CP(G4NURBS::t_CtrlPt & rcp, t_Coord x, t_Coord y, t_Coord z, t_Coord w);
static void CP(G4NURBS::t_CtrlPt & rcp, t_Coord x, t_Coord y, t_Coord z, t_Coord w, G4Float factor);
private:
// check function used internally by constructors.
// no returned value because all errors reported are fatals.
// (assume order + nbrCtrlPts == nbrKnots
// cf constructors to understand why)
void Conscheck() const;
// copy constructor.
// Not really necessary for geant. A warning is issued when used.
G4NURBS(const G4NURBS &);
};
// external representation for t_KnotVectorGenFlag
ostream & operator << (ostream & inout_OutStream, G4NURBS::t_KnotVectorGenFlag in_KVGFlag);
// << overload to dump a nurbs
// writted with public access functions
// do not depends on protected part
ostream & operator << (ostream & inout_outStream, const G4NURBS & in_kNurb);
/***********************************************************************
* *
* Inline code for public access functions. *
* depends on the protected part *
* *
***********************************************************************/
inline G4int G4NURBS::GetUorder() const { return m[U].order; }
inline G4int G4NURBS::GetVorder() const { return m[V].order; }
inline G4int G4NURBS::GetUnbrKnots() const { return m[U].nbrKnots; }
inline G4int G4NURBS::GetVnbrKnots() const { return m[V].nbrKnots; }
inline G4int G4NURBS::GetUnbrCtrlPts() const { return m[U].nbrCtrlPts; }
inline G4int G4NURBS::GetVnbrCtrlPts() const { return m[V].nbrCtrlPts; }
inline G4int G4NURBS::GettotalnbrCtrlPts() const { return mtotnbrCtrlPts; }
inline G4double G4NURBS::GetUmin() const {
return (G4double) m[U].pKnots[GetUorder()-1];
}
inline G4double G4NURBS::GetUmax() const {
return (G4double) m[U].pKnots[GetUnbrCtrlPts()];
}
inline G4double G4NURBS::GetVmin() const {
return (G4double) m[V].pKnots[GetVorder()-1];
}
inline G4double G4NURBS::GetVmax() const {
return (G4double) m[V].pKnots[GetVnbrCtrlPts()];
}
inline G4int G4NURBS::Getorder(G4NURBS::t_direction in_dir) const {
return m[in_dir & DMask].order;
}
inline G4int G4NURBS::GetnbrKnots(G4NURBS::t_direction in_dir) const {
return m[in_dir & DMask].nbrKnots;
}
inline G4int G4NURBS::GetnbrCtrlPts(G4NURBS::t_direction in_dir) const {
return m[in_dir & DMask].nbrCtrlPts;
}
inline char G4NURBS::Tochar(G4NURBS::t_direction in_dir) {
return (in_dir?'V':'U');
}
/***********************************************************************
* *
* inline code for protected functions *
* *
***********************************************************************/
// convert two dim. index to one dim.
//( Ctrl Pts are stored U increasing first )
// no check.
inline G4NURBS::t_indCtrlPt
G4NURBS::To1d(t_inddCtrlPt in_Uindex, t_inddCtrlPt in_Vindex) const {
return in_Uindex + in_Vindex*m[U].nbrCtrlPts;
}
// return a float copy
inline G4NURBS::t_floatCtrlPt*
G4NURBS::TofloatCtrlPt(const t_CtrlPt & in_krcp) {
G4NURBS::t_floatCtrlPt * pcopy = new G4NURBS::t_floatCtrlPt [1];
for (G4int indCoord = X; indCoord < NofC; indCoord++)
(*pcopy)[indCoord] = (G4float)in_krcp[indCoord];
return pcopy;
}
// return a double copy
inline G4NURBS::t_doubleCtrlPt*
G4NURBS::TodoubleCtrlPt(const t_CtrlPt & in_krcp) {
G4NURBS::t_doubleCtrlPt * pcopy = new G4NURBS::t_doubleCtrlPt [1];
for (G4int indCoord = X; indCoord < NofC; indCoord++)
(*pcopy)[indCoord] = (G4double)in_krcp[indCoord];
return pcopy;
}
// MakeKnotVector alias
inline G4bool G4NURBS::MakeKnotVector(G4NURBS::t_Dir * p_inoutdirdat, G4NURBS::t_KnotVectorGenFlag in_KVGFlag) {
return MakeKnotVector(*p_inoutdirdat, in_KVGFlag);
}
/***********************************************************************
* *
* inlines functions to simplify control points definition *
* see GG4NURBSbox.cc for instance *
* *
***********************************************************************/
inline void G4NURBS::CP(G4NURBS::t_CtrlPt & rcp,
t_Coord x, t_Coord y, t_Coord z, t_Coord w) {
rcp[G4NURBS::X]=x;
rcp[G4NURBS::Y]=y;
rcp[G4NURBS::Z]=z;
rcp[G4NURBS::W]=w;
}
// with a common factor
inline void G4NURBS::CP(G4NURBS::t_CtrlPt & rcp, t_Coord x, t_Coord y, t_Coord z, t_Coord w, G4Float factor) {
rcp[G4NURBS::X]=factor*x;
rcp[G4NURBS::Y]=factor*y;
rcp[G4NURBS::Z]=factor*z;
rcp[G4NURBS::W]=factor*w;
}
#endif /* end of __C_G4NURBS__ */
@@ -0,0 +1,34 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4NURBSbox.hh,v 2.1 1998/07/12 02:59:11 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// Olivier Crumeyrolle 12 September 1996
// Box builder prototype
// OC 060996
#include "G4NURBS.hh"
#ifndef __C_G4NURBSbox__
#define __C_G4NURBSbox__ 1
class G4NURBSbox : public G4NURBS
{
public: G4NURBSbox(G4double DX, G4double DY, G4double DZ);
virtual const char* Whoami() const;
};
#endif
// end of __C_G4NURBSbox__
@@ -0,0 +1,34 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4NURBScylinder.hh,v 2.1 1998/07/12 02:59:11 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// Olivier Crumeyrolle 12 September 1996
// Cylinder builder prototype
// OC 090796
#include "G4NURBS.hh"
#ifndef __C_G4NURBScylinder__
#define __C_G4NURBScylinder__ 1
class G4NURBScylinder : public G4NURBS
{
public: G4NURBScylinder(G4double R, G4double DZ);
virtual const char* Whoami() const;
};
#endif
// end of __C_G4NURBScylinder__
@@ -0,0 +1,49 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4NURBShexahedron.hh,v 2.1 1998/07/12 02:59:12 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
// Hexa hedron builder prototype
// OC 17 9 96
#include "G4NURBS.hh"
#include "G4ThreeVector.hh"
#ifndef __C_G4NURBShexahedron__
#define __C_G4NURBShexahedron__ 1
class G4NURBShexahedron : public G4NURBS
{
// imagine the hexahedron is just a box, then
// the eight corners must be given in the following order :
// DX DY -DZ
// -DX DY -DZ
// -DX -DY -DZ
// DX -DY -DZ
// DX DY DZ
// -DX DY DZ
// -DX -DY DZ
// DX -DY DZ
// (ie, with Oz pointing to you, Ox on the right, Oy on the top:
// from the rear, from the upper right corner to the lower one
// in anticlockwise sens, then the same for front side)
public: G4NURBShexahedron(const G4ThreeVector Corners [8]);
virtual const char* Whoami() const;
};
#endif
// end of __C_G4NURBShexahedron__
@@ -0,0 +1,34 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4NURBStube.hh,v 2.1 1998/07/12 02:59:13 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// Olivier Crumeyrolle 12 September 1996
// Tube builder prototype
// OC 090796
#include "G4NURBS.hh"
#ifndef __C_G4NURBStube__
#define __C_G4NURBStube__ 1
class G4NURBStube : public G4NURBS
{
public: G4NURBStube(G4double RMIN, G4double RMAX, G4double DZ);
virtual const char* Whoami() const;
};
#endif
// end of __C_G4NURBStube__
@@ -0,0 +1,53 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4NURBStubesector.hh,v 2.1 1998/07/12 02:59:14 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// Olivier Crumeyrolle 12 September 1996
// Tubesector builder prototype
// OC 290896
#include "G4NURBS.hh"
#ifndef __C_G4NURBStubesector__
#define __C_G4NURBStubesector__ 1
class G4NURBStubesector : public G4NURBS
{
public:
// angle in radians
// If PHI2 smaller (or equal) than PHI1 , it is incremented
// by 2pi as necessary to become strictly greater.
// Except that, you can use any value for the arguments,
// it's the renderer or you that will have troubles.
G4NURBStubesector(G4double RMIN, G4double RMAX, G4double DZ, G4double PHI1, G4double PHI2);
virtual const char* Whoami() const;
virtual ~G4NURBStubesector();
protected:
char * mpwhoami;
private:
static t_inddCtrlPt DecideNbrCtrlPts(G4double PHI1, G4double PHI2);
};
#endif
// end of __C_G4NURBStubesector__
@@ -0,0 +1,35 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Point3DList.hh,v 2.0 1998/07/02 17:30:02 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison July 1995
#ifndef G4POINT3DLIST_HH
#define G4POINT3DLIST_HH
#include <rw/tvordvec.h>
#include "G4Point3D.hh"
class ostream;
class G4Point3DList: public RWTValOrderedVector<G4Point3D> {
friend ostream& operator << (ostream& os, const G4Point3DList& points);
public:
virtual ~G4Point3DList();
// Destructor.
};
#include "G4Point3DList.icc"
#endif
@@ -0,0 +1,14 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Point3DList.icc,v 2.0 1998/07/02 17:30:04 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison July 1995
inline G4Point3DList::~G4Point3DList () {}
@@ -0,0 +1,342 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Polyhedron.hh,v 2.2 1998/07/13 16:56:10 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
//
// G4Polyhedron is an intermediate class between G4 and visualization
// systems. It is intended to provide some service like:
// - polygonization of the G4 shapes with triangulization
// (quadrilaterization) of complex polygons;
// - calculation of normals for faces and vertices;
//
// Public constructors:
// G4PolyhedronBox(dx,dy,dz) - create G4Polyhedron for G4 Box;
// G4PolyhedronTrd1(dx1,dx2,dy,dz) - create G4Polyhedron for G4 Trd1;
// G4PolyhedronTrd2(dx1,dx2,dy1,dy2,dz) - create G4Polyhedron for G4 Trd2;
// G4PolyhedronTrap(dz,theta,phi,
// h1,bl1,tl1,alp1,
// h2,bl2,tl2,alp2) - create G4Polyhedron for G4 Trap;
// G4PolyhedronPara(dx,dy,dz,
// alpha,theta,phi) - create G4Polyhedron for G4 Para;
//
// G4PolyhedronTube(rmin,rmax,dz) - create G4Polyhedron for G4 Tube;
// G4PolyhedronTubs(rmin,rmax,dz,
// phi1,dphi) - create G4Polyhedron for G4 Tubs;
// G4PolyhedronCone(rmin1,rmax1,
// rmin2,rmax2,dz) - create G4Polyhedron for G4 Cone;
// G4PolyhedronCons(rmin1,rmax1,
// rmin2,rmax2,dz,
// phi1,dphi) - create G4Polyhedron for G4 Cons;
//
// G4PolyhedronPgon(phi,dphi,npdv,nz,
// z(*),rmin(*),rmax(*)) - create G4Polyhedron for G4 Pgon;
// G4PolyhedronPcon(phi,dphi,nz,
// z(*),rmin(*),rmax(*)) - create G4Polyhedron for G4 Pcon;
//
// G4PolyhedronSphere(rmin,rmax,
// phi,dphi,the,dthe) - create G4Polyhedron for Sphere;
// G4PolyhedronTorus(rmin,rmax,rtor,
// phi,dphi) - create G4Polyhedron for Torus;
//
// Public functions:
// GetNoVertices() - returns number of vertices
// GetNoFacets() - returns number of faces
// GetNextVertexIndex(index, edgeFlag) - get vertex indeces of the
// quadrilaterals in order; returns false when
// finished each face;
// GetVertex(index) - returns vertex by index;
// GetNextVertex(vertex, edgeFlag) - get vertices with edge visibility
// of the quadrilaterals in order;
// returns false when finished each face;
// GetNextVertex(vertex, edgeFlag, normal) - get vertices with edge
// visibility and normal of the quadrilaterals
// in order; returns false when finished each face;
// GetNextNormal(normal) - get normals of each face in order;
// returns false when finished all faces;
// GetNextUnitNormal(normal) - get normals of unit length of each face
// in order; returns false when finished all faces;
// GetNextEdgeIndeces(i1, i2, edgeFlag) - get indeces of the next edge;
// returns false for the last edge;
// GetNextEdge(p1, p2, edgeFlag) - get next edge;
// returns false for the last edge;
// SetNumberOfRotationSteps(G4int n) - Set number of steps for whole circle;
// History:
// 20.06.96 Evgeni Chernyaev <Evgueni.Tcherniaev@cern.ch> - initial version
//
// 23.07.96 John Allison
// - added GetNoVertices, GetNoFacets, GetNextVertex, GetNextNormal
//
// 30.09.96 E.Chernyaev
// - added GetNextVertexIndex, GetVertex by Yasuhide Sawada
// - added GetNextUnitNormal, GetNextEdgeIndeces, GetNextEdge
// - improvements: angles now expected in radians
// int -> G4int, double -> G4double
// - G4ThreeVector replaced by either G4Point3D or G4Normal3D
//
// 15.12.96 E.Chernyaev
// - private functions G4PolyhedronAlloc, G4PolyhedronPrism renamed
// to AllocateMemory and CreatePrism
// - added private functions GetNumberOfRotationSteps, RotateEdge,
// RotateAroundZ, SetReferences
// - rewritten G4PolyhedronCons;
// - added G4PolyhedronPara, ...Trap, ...Pgon, ...Pcon, ...Sphere, ...Torus,
// so full List of implemented shapes now looks like:
// BOX, TRD1, TRD2, TRAP, TUBE, TUBS, CONE, CONS, PARA, PGON, PCON,
// SPHERE, TORUS
//
// 01.06.97 E.Chernyaev
// - RotateAroundZ modified and SetSideFacets added to allow Rmin=Rmax
// in bodies of revolution
//
// 24.06.97 J.Allison
// - added static private member fNumberOfRotationSteps and static public
// functions void SetNumberOfRotationSteps (G4int n) and
// void ResetNumberOfRotationSteps (). Modified
// GetNumberOfRotationSteps() appropriately. Made all three functions
// inline (at end of this .hh file).
// Usage:
// G4Polyhedron::SetNumberOfRotationSteps
// (fpView -> GetViewParameters ().GetNoOfSides ());
// pPolyhedron = solid.CreatePolyhedron ();
// G4Polyhedron::ResetNumberOfRotationSteps ();
#ifndef G4POLYHEDRON_HH
#define G4POLYHEDRON_HH
#include "G4ios.hh"
#include "G4VVisPrim.hh"
#include "G4Point3D.hh"
#include "G4Normal3D.hh"
class G4Facet {
friend class G4Polyhedron;
friend ostream& operator<<(ostream&, const G4Facet &facet);
private:
struct G4Edge { G4int v,f; };
G4Edge edge[4];
public:
G4Facet(G4int v1=0, G4int f1=0, G4int v2=0, G4int f2=0,
G4int v3=0, G4int f3=0, G4int v4=0, G4int f4=0)
{ edge[0].v=v1; edge[0].f=f1; edge[1].v=v2; edge[1].f=f2;
edge[2].v=v3; edge[2].f=f3; edge[3].v=v4; edge[3].f=f4; }
};
class G4Polyhedron: public G4VVisPrim {
friend ostream& operator<<(ostream&, const G4Polyhedron &ph);
private:
static G4int fNumberOfRotationSteps;
protected:
G4int nvert, nface;
G4Point3D *pV;
G4Facet *pF;
// Allocate memory for G4Polyhedron
void AllocateMemory(G4int Nvert, G4int Nface);
// Create G4Polyhedron for prism with quadrilateral base
void CreatePrism();
// Get number of steps for whole circle
G4int GetNumberOfRotationSteps();
// Generate facets by revolving an edge around Z-axis
void RotateEdge(G4int k1, G4int k2, G4double r1, G4double r2,
G4int v1, G4int v2, G4int vEdge,
G4bool ifWholeCircle, G4int ns, G4int &kface);
// Set side facets for the case of incomplete rotation
void SetSideFacets(G4int ii[4], G4int vv[4],
G4int *kk, G4double *r,
G4double dphi, G4int ns, G4int &kface);
// Create G4Polyhedron for body of revolution around Z-axis
void RotateAroundZ(G4int nstep, G4double phi, G4double dphi,
G4int np1, G4int np2,
const G4double *z, G4double *r,
G4int nodeVis, G4int edgeVis);
// For each edge set reference to neighbouring facet
void SetReferences();
public:
// Constructor
G4Polyhedron(G4int Nvert=0, G4int Nface=0)
: nvert(Nvert), nface(Nface),
pV(Nvert ? new G4Point3D[Nvert+1] : 0),
pF(Nface ? new G4Facet[Nface+1] : 0) {}
// Copy constructor
G4Polyhedron(const G4Polyhedron &from);
// Destructor
~G4Polyhedron() { delete [] pV; delete [] pF; }
// Assignment
G4Polyhedron& operator=(const G4Polyhedron &from);
// Get number of vertices
G4int GetNoVertices() const { return nvert; }
// Get number of facets
G4int GetNoFacets() const { return nface; }
// Get next vertex index of the quadrilateral
G4bool GetNextVertexIndex(G4int &index, G4int &edgeFlag) const;
// Get vertex by index
G4Point3D GetVertex(G4int index) const;
// Get next vertex + edge visibility of the quadrilateral
G4bool GetNextVertex(G4Point3D &vertex, G4int &edgeFlag) const;
// Get next vertex + edge visibility + normal of the quadrilateral
//G4bool GetNextVertex
//(G4Point3D &vertex, G4int &edgeFlag, G4Normal3D &normal) const;
// Get normal of the next face
G4bool GetNextNormal(G4Normal3D &normal) const;
// Get normal of unit length of the next face
G4bool GetNextUnitNormal(G4Normal3D &normal) const;
// Get indeces of the next edge
G4bool GetNextEdgeIndeces(G4int &i1, G4int &i2, G4int &edgeFlag) const;
// Get next edge
G4bool GetNextEdge(G4Point3D &p1, G4Point3D &p2, G4int &edgeFlag) const;
// Set number of steps for whole circle
static void SetNumberOfRotationSteps(G4int n);
// Reset number of steps for whole circle to default value
static void ResetNumberOfRotationSteps();
};
class G4PolyhedronTrd2 : public G4Polyhedron {
public:
G4PolyhedronTrd2(G4double Dx1, G4double Dx2,
G4double Dy1, G4double Dy2, G4double Dz);
};
class G4PolyhedronTrd1 : public G4PolyhedronTrd2 {
public:
G4PolyhedronTrd1(G4double Dx1, G4double Dx2, G4double Dy, G4double Dz) :
G4PolyhedronTrd2(Dx1, Dx2, Dy, Dy, Dz) {}
};
class G4PolyhedronBox : public G4PolyhedronTrd2 {
public:
G4PolyhedronBox(G4double Dx, G4double Dy, G4double Dz) :
G4PolyhedronTrd2(Dx, Dx, Dy, Dy, Dz) {}
};
class G4PolyhedronTrap : public G4Polyhedron {
public:
G4PolyhedronTrap(G4double Dz, G4double Theta, G4double Phi,
G4double Dy1, G4double Dx1, G4double Dx2, G4double Alp1,
G4double Dy2, G4double Dx3, G4double Dx4, G4double Alp2);
};
class G4PolyhedronPara : public G4PolyhedronTrap {
public:
G4PolyhedronPara(G4double Dx, G4double Dy, G4double Dz,
G4double Alpha, G4double Theta, G4double Phi) :
G4PolyhedronTrap(Dz, Theta, Phi, Dy, Dx, Dx, Alpha, Dy, Dx, Dx, Alpha) {}
};
class G4PolyhedronCons : public G4Polyhedron {
public:
G4PolyhedronCons(G4double Rmn1, G4double Rmx1,
G4double Rmn2, G4double Rmx2, G4double Dz,
G4double Phi1, G4double Dphi);
};
class G4PolyhedronCone : public G4PolyhedronCons {
public:
G4PolyhedronCone(G4double Rmn1, G4double Rmx1,
G4double Rmn2, G4double Rmx2, G4double Dz)
: G4PolyhedronCons(Rmn1, Rmx1, Rmn2, Rmx2, Dz, 0*deg, 360*deg) {}
};
class G4PolyhedronTubs : public G4PolyhedronCons {
public:
G4PolyhedronTubs(G4double Rmin, G4double Rmax, G4double Dz,
G4double Phi1, G4double Dphi)
: G4PolyhedronCons(Rmin, Rmax, Rmin, Rmax, Dz, Phi1, Dphi) {}
};
class G4PolyhedronTube : public G4PolyhedronCons {
public:
G4PolyhedronTube (G4double Rmin, G4double Rmax, G4double Dz)
: G4PolyhedronCons(Rmin, Rmax, Rmin, Rmax, Dz, 0*deg, 360*deg) {}
};
class G4PolyhedronPgon : public G4Polyhedron {
public:
G4PolyhedronPgon(G4double phi, G4double dphi, G4int npdv, G4int nz,
const G4double *z,
const G4double *rmin,
const G4double *rmax);
};
class G4PolyhedronPcon : public G4PolyhedronPgon {
public:
G4PolyhedronPcon(G4double phi, G4double dphi, G4int nz,
const G4double *z,
const G4double *rmin,
const G4double *rmax)
: G4PolyhedronPgon(phi, dphi, 0, nz, z, rmin, rmax) {}
};
class G4PolyhedronSphere : public G4Polyhedron {
public:
G4PolyhedronSphere(G4double rmin, G4double rmax,
G4double phi, G4double dphi,
G4double the, G4double dthe);
};
class G4PolyhedronTorus : public G4Polyhedron {
public:
G4PolyhedronTorus(G4double rmin, G4double rmax, G4double rtor,
G4double phi, G4double dphi);
};
inline G4int G4Polyhedron::GetNumberOfRotationSteps()
/***********************************************************************
* *
* Name: G4Polyhedron::GetNumberOfRotationSteps Date: 11.12.96 *
* Author: E.Chernyaev (IHEP/Protvino) Revised: 24.06.97 *
* *
* Function: Get number of steps for whole circle *
* *
***********************************************************************/
{
return fNumberOfRotationSteps;
}
inline void G4Polyhedron::ResetNumberOfRotationSteps()
/***********************************************************************
* *
* Name: G4Polyhedron::ResetNumberOfRotationSteps Date: 24.06.97 *
* Author: J.Allison (Manchester University) Revised: *
* *
* Function: Reset number of steps for whole circle to default value *
* *
***********************************************************************/
{
fNumberOfRotationSteps = 24;
}
#endif /* G4POLYHEDRON_HH */
@@ -0,0 +1,29 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Polyline.hh,v 2.0 1998/07/02 17:30:06 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison July 1995
#ifndef G4POLYLINE_HH
#define G4POLYLINE_HH
#include "G4VVisPrim.hh"
#include "G4Point3DList.hh"
class G4Polyline: public G4VVisPrim, public G4Point3DList {
friend ostream& operator << (ostream& os, const G4Polyline& line);
public:
G4Polyline ();
G4Polyline (const G4VVisPrim& prim);
};
inline G4Polyline::G4Polyline () {}
#endif
@@ -0,0 +1,33 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Polymarker.hh,v 2.0 1998/07/02 17:30:08 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison November 1996
#ifndef G4POLYMARKER_HH
#define G4POLYMARKER_HH
#include "G4VMarker.hh"
#include "G4Point3DList.hh"
class G4Polymarker: public G4VMarker, public G4Point3DList {
public:
friend ostream& operator << (ostream& os, const G4Polymarker& marker);
enum MarkerType {line, dots, circles, squares};
G4Polymarker ();
MarkerType GetMarkerType () const;
void SetMarkerType (MarkerType type);
private:
MarkerType fMarkerType;
};
#include "G4Polymarker.icc"
#endif
@@ -0,0 +1,20 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Polymarker.icc,v 2.0 1998/07/02 17:30:09 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison November 1996
inline G4Polymarker::MarkerType G4Polymarker::GetMarkerType () const {
return fMarkerType;
}
inline void G4Polymarker::SetMarkerType (MarkerType type) {
fMarkerType = type;
}
+28
View File
@@ -0,0 +1,28 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Square.hh,v 2.0 1998/07/02 17:29:48 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 17/11/96.
#ifndef G4SQUARE_HH
#define G4SQUARE_HH
#include "G4VMarker.hh"
class G4Square: public G4VMarker {
public:
G4Square ();
G4Square (const G4Point3D& pos);
G4Square (const G4VMarker& marker);
};
#include "G4Square.icc"
#endif
+20
View File
@@ -0,0 +1,20 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Square.icc,v 2.0 1998/07/02 17:30:10 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 17/11/96.
inline G4Square::G4Square () {}
inline G4Square::G4Square (const G4Point3D& pos):
G4VMarker (pos) {}
inline G4Square::G4Square (const G4VMarker& marker):
G4VMarker (marker) {}
+45
View File
@@ -0,0 +1,45 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Text.hh,v 2.0 1998/07/02 17:30:12 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 17/11/96.
#ifndef G4TEXT_HH
#define G4TEXT_HH
#include "G4VMarker.hh"
#include "globals.hh"
class G4Text: public G4VMarker {
public:
enum Layout {left, centre, right};
G4Text (const G4String& text);
G4Text (const G4String& text, const G4Point3D& pos);
G4Text (const G4VMarker& marker);
G4String GetText () const;
Layout GetLayout () const;
G4double GetXOffset () const ;
G4double GetYOffset () const ;
void SetText (const G4String& text);
void SetLayout (Layout layout);
void SetOffset ( double dx, double dy ) ;
private:
G4String fText;
Layout fLayout;
G4double fXOffset, fYOffset ;
};
#include "G4Text.icc"
#endif
+44
View File
@@ -0,0 +1,44 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Text.icc,v 2.0 1998/07/02 17:30:13 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 17/11/96.
inline G4String G4Text::GetText () const {
return fText;
}
inline G4Text::Layout G4Text::GetLayout () const {
return fLayout;
}
inline void G4Text::SetText (const G4String& text) {
fText = text;
}
inline void G4Text::SetLayout (G4Text::Layout layout) {
fLayout = layout;
}
inline G4double G4Text::GetXOffset () const
{
return fXOffset ;
}
inline G4double G4Text::GetYOffset () const
{
return fYOffset ;
}
inline void G4Text::SetOffset ( double x_offset, double y_offset )
{
fXOffset = x_offset ;
fYOffset = y_offset ;
}
@@ -0,0 +1,78 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VGraphicsScene.hh,v 2.0 1998/07/02 17:30:16 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 19th July 1996
// Abstract interface class for the concept of a graphics scene.
// It is a minimal scene for the GEANT4 kernel.
// See G4VScene for a fuller description. G4VScene is the full abstract
// interface to graphics systems.
#ifndef G4VGRAPHICSSCENE_HH
#define G4VGRAPHICSSCENE_HH
class G4VisAttributes;
class G4VSolid;
class G4Box;
class G4Cons;
class G4Tubs;
class G4Trd;
class G4Trap;
class G4Sphere;
class G4Para;
class G4Torus;
class G4PhysicalVolumeModel;
#include "G4Transform3D.hh"
// Scene Interface - begin snippet.
class G4VGraphicsScene {
public:
///////////////////////////////////////////////////////////////////
// Functions for adding raw GEANT4 objects. The concrete graphics
// scene has the option of implementing its own model or asking the
// solid to provide a G4Polyhedron or similar primitive - see, for
// example, G4VScene in the Visualization Category.
virtual void AddThis (const G4Box& box) = 0;
virtual void AddThis (const G4Cons& cons) = 0;
virtual void AddThis (const G4Tubs& tubs) = 0;
virtual void AddThis (const G4Trd& trd) = 0;
virtual void AddThis (const G4Trap& trap) = 0;
virtual void AddThis (const G4Sphere& sphere) = 0;
virtual void AddThis (const G4Para& para ) = 0;
virtual void AddThis (const G4Torus& torus ) = 0;
virtual void AddThis (const G4VSolid& solid) = 0; // For solids not above.
///////////////////////////////////////////////////////////////////
// Other functions.
virtual void EstablishSpecials (G4PhysicalVolumeModel&) {}
// Used to establish any special relationships between scene and
// this particular type of model - non-pure, i.e., no requirement to
// implement. See G4PhysicalVolumeModel.hh for details.
virtual void DecommissionSpecials (G4PhysicalVolumeModel&) {}
// Used to reverse the effect of EstablishSpecials, if required.
virtual void PreAddThis (const G4Transform3D& objectTransformation,
const G4VisAttributes& visAttribs) = 0;
// objectTransformation is the transformation in the world
// coordinate system of the object about to be added, and
// visAttribs is its visualization attributes.
virtual void PostAddThis () = 0;
};
// Scene Interface - end snippet.
#endif
+123
View File
@@ -0,0 +1,123 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VMarker.hh,v 2.3 1998/11/09 02:37:42 stanaka Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// G4VMarker - base class for markers - circles, squares, etc.
// John Allison 17/11/96.
// G4VMarkers are 2-dimensional G4VVisPrims with the special
// properties (a) of always facing the camera and (b) of having the
// possibility of a size defined in screen units. The convention is
// that if a world size is not specified, then the marker will be
// drawn to the given screen size or paper size regardless of the
// viewing transformation in effect.
//
// "Size" means "overall size", e.g., diameter of circle, side of
// Square, height of text (but Diameter and Radius access functions
// are defined to avoid ambiguity).
//
// So the user who constructs the marker decides whether it should be
// drawn to a given size in world coordinates by setting the world
// size. Alternatively, the user can set the screen size (internally,
// the world size is set to zero) and the marker is drawn to its
// screen size. Finally, the user may decide not to set any size; in
// that case, it is drawn according to the sizes specified in the
// default marker specified in G4ViewParameters.
//
// Also in G4ViewParameters is a "global marker scale" which is a
// factor by which all marker sizes are multiplied before drawing.
//
// Thus the graphics system driver scene code might look like:
//
// void G4XXXGraphicsScene::AddPrimitive (const G4Circle& circle) {
// G4bool hidden = !(fpView -> GetViewParameters().IsMarkerNotHidden());
// const G4Colour& colour = GetColour (circle); // Base class GetColour.
// G4VMarker::FillStyle style = circle.GetFillStyle();
// const G4Point3D& centre = circle.GetPosition();
// MarkerSizeType sizeType;
// G4double size = GetMarkerSize (circle, sizeType);
// switch (sizeType) {
// default:
// case screen:
// // Draw in screen coordinates.
// // ...
// break;
// case world:
// // Draw in world coordinates.
// // ...
// break;
// }
// }
#ifndef G4VMARKER_HH
#define G4VMARKER_HH
#include "globals.hh"
#include "G4VVisPrim.hh"
#include "G4Point3D.hh"
#include "G4Colour.hh"
#include "G4Color.hh"
class G4VMarker: public G4VVisPrim {
friend ostream& operator << (ostream& os, const G4VMarker& marker);
friend G4bool operator != (const G4VMarker& m1,
const G4VMarker& m2);
public:
enum FillStyle {noFill, hashed, filled};
//////////////////////////////////////////////////////
// Constructors...
G4VMarker ();
G4VMarker (const G4VMarker& marker);
G4VMarker& operator = (const G4VMarker& right);
G4VMarker (const G4Point3D& pos);
/////////////////////////////////////////////////////
// Get functions...
G4Point3D GetPosition () const;
G4double GetWorldSize () const;
G4double GetWorldDiameter () const;
G4double GetWorldRadius () const;
G4double GetScreenSize () const;
G4double GetScreenDiameter () const;
G4double GetScreenRadius () const;
FillStyle GetFillStyle () const;
/////////////////////////////////////////////////////
// Set functions...
void SetPosition (const G4Point3D&);
void SetWorldSize (G4double);
void SetWorldDiameter (G4double);
void SetWorldRadius (G4double);
void SetScreenSize (G4double);
void SetScreenDiameter (G4double);
void SetScreenRadius (G4double);
void SetFillStyle (FillStyle);
// Access functions to the string for user custimizable information
virtual const G4String& GetInfo() const { return fInfo ;}
virtual void SetInfo( const G4String& info ){ fInfo = info ;}
private:
G4Point3D fPosition;
G4double fWorldSize; // Default 0. means use screen size.
G4double fScreenSize; // Default 0. means use global default.
FillStyle fFillStyle;
// String for user customizable information
G4String fInfo ;
};
#include "G4VMarker.icc"
#endif
+117
View File
@@ -0,0 +1,117 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VMarker.icc,v 2.2 1998/11/09 02:37:43 stanaka Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
inline G4VMarker::G4VMarker ():
fPosition (G4Point3D ()),
fWorldSize (0.),
fScreenSize (0.),
fFillStyle (noFill),
fInfo()
{}
inline G4VMarker::G4VMarker (const G4VMarker& marker):
G4VVisPrim (marker),
fPosition (marker.fPosition),
fWorldSize (marker.fWorldSize),
fScreenSize (marker.fScreenSize),
fFillStyle (marker.fFillStyle),
fInfo (marker.fInfo)
{}
inline G4VMarker& G4VMarker::operator = (const G4VMarker& right) {
((G4VVisPrim*) this) -> operator = (right);
fPosition = right.fPosition;
fWorldSize = right.fWorldSize;
fScreenSize = right.fScreenSize;
fFillStyle = right.fFillStyle;
fInfo = right.fInfo;
return *this;
}
inline G4VMarker::G4VMarker (const G4Point3D& pos):
fPosition (pos),
fWorldSize (0.),
fScreenSize (0.),
fFillStyle (noFill),
fInfo ()
{}
inline G4Point3D G4VMarker::GetPosition () const {
return fPosition;
}
inline G4double G4VMarker::GetWorldSize () const {
return fWorldSize;
}
inline G4double G4VMarker::GetWorldDiameter () const {
return fWorldSize;
}
inline G4double G4VMarker::GetWorldRadius () const {
return fWorldSize / 2.;
}
inline G4double G4VMarker::GetScreenSize () const {
return fScreenSize;
}
inline G4double G4VMarker::GetScreenDiameter () const {
return fScreenSize;
}
inline G4double G4VMarker::GetScreenRadius () const {
return fScreenSize / 2.;
}
inline G4VMarker::FillStyle G4VMarker::GetFillStyle () const {
return fFillStyle;
}
inline void G4VMarker::SetPosition (const G4Point3D& pos) {
fPosition = pos;
}
inline void G4VMarker::SetWorldSize (G4double ws) {
fWorldSize = ws;
}
inline void G4VMarker::SetWorldDiameter (G4double wd) {
fWorldSize = wd;
}
inline void G4VMarker::SetWorldRadius (G4double wr) {
fWorldSize = 2. * wr;
}
inline void G4VMarker::SetScreenSize (G4double ss) {
fWorldSize = 0.;
fScreenSize = ss;
}
inline void G4VMarker::SetScreenDiameter (G4double sd) {
fWorldSize = 0.;
fScreenSize = sd;
}
inline void G4VMarker::SetScreenRadius (G4double sr) {
fWorldSize = 0.;
fScreenSize = 2. * sr;
}
inline void G4VMarker::SetFillStyle (G4VMarker::FillStyle style) {
fFillStyle = style;
}
@@ -0,0 +1,117 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VVisManager.hh,v 2.4 1998/09/25 11:54:18 allison Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// Abstract interface for GEANT4 Visualization Manager.
// John Allison 19/Oct/1996.
// This is a "Singleton", i.e., only one instance of it may exist.
// This is ensured by making the constructor private.
// It has only one public access function which is used to obtain a pointer
// to the concrete G4VisManager, should it exist.
// G4VVisManager* pVVMan = G4VVisManager::GetConcreteInstance ();
// points to the real (concrete) G4VisManager, if a view is available for
// drawing, otherwise is zero. Thus all code must be protected,
// for example, by:
// if (pVVMan) pVVMan -> Draw (polyline);
#ifndef G4VVISMANAGER_HH
#define G4VVISMANAGER_HH
#include "G4Transform3D.hh"
#include "G4ThreeVector.hh" // Just a typedef Hep3Vector.
#include "G4RotationMatrix.hh" // Just a typedef HepRotation.
class G4Polyline;
class G4Text;
class G4Circle;
class G4Square;
class G4Polymarker;
class G4Polyhedron;
class G4NURBS;
class G4VSolid;
class G4LogicalVolume;
class G4VPhysicalVolume;
class G4VisAttributes;
class G4VVisManager {
public:
static G4VVisManager* GetConcreteInstance ();
// Returns pointer to actual visualization manager if a view is
// available for drawing, else returns null. Always check value.
virtual ~G4VVisManager () {}
///////////////////////////////////////////////////////////////////
// Functions to Draw "transient" objects, useful for hits, digis, etc.
//1 Note that the {\tt G4Transform3D} objects refer to the
//1 transformation of the {\em object} being drawn. However, for
//1 some functions, there is a version which takes a {\tt
//1 G4Translation} and a {\tt G4RotationMatrix}, the latter being a
//1 {\em system} rotation, as in {\tt G4PVPlacement}.
//1
//1 Note also that where a {\tt G4VisAttributes} argument is
//1 specified, it overrides any attributes belonging to the object
//1 itself. Otherwise, the visualization attributes are assumed to
//1 be those belonging to the object being drawn (you can set its
//1 attributes --- see Section \ref{ap:setting_attribs}).
// VVisManager Interface - begin snippet.
virtual void Draw (const G4Polyline&,
const G4Transform3D& objectTransformation = G4Transform3D::Identity) = 0;
virtual void Draw (const G4Text&,
const G4Transform3D& objectTransformation = G4Transform3D::Identity) = 0;
virtual void Draw (const G4Circle&,
const G4Transform3D& objectTransformation = G4Transform3D::Identity) = 0;
virtual void Draw (const G4Square&,
const G4Transform3D& objectTransformation = G4Transform3D::Identity) = 0;
virtual void Draw (const G4Polymarker&,
const G4Transform3D& objectTransformation = G4Transform3D::Identity) = 0;
virtual void Draw (const G4Polyhedron&,
const G4Transform3D& objectTransformation = G4Transform3D::Identity) = 0;
virtual void Draw (const G4NURBS&,
const G4Transform3D& objectTransformation = G4Transform3D::Identity) = 0;
virtual void Draw (const G4VSolid&, const G4VisAttributes&,
const G4Transform3D& objectTransformation = G4Transform3D::Identity) = 0;
virtual void Draw (const G4LogicalVolume&, const G4VisAttributes&,
const G4Transform3D& objectTransformation = G4Transform3D::Identity) = 0;
virtual void Draw (const G4VPhysicalVolume&, const G4VisAttributes&,
const G4Transform3D& objectTransformation = G4Transform3D::Identity) = 0;
// VVisManager Interface - end snippet.
// Other management functions...
virtual void GeometryHasChanged () = 0;
// This is used by the run manager to notify a change of geometry.
protected:
static G4VVisManager* fpConcreteInstance; // Pointer to real G4VisManager.
};
inline G4VVisManager* G4VVisManager::GetConcreteInstance () {
return fpConcreteInstance;
}
#endif
@@ -0,0 +1,42 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VVisPrim.hh,v 2.0 1998/07/02 17:30:23 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison August 1995
// Virtual base class for Visualization Primitives
// (or Visualization Representations, as they are sometimes called).
#ifndef G4VVISPRIM_HH
#define G4VVISPRIM_HH
#include "globals.hh"
#include "G4Visible.hh"
class ostream;
class G4VisAttributes;
class G4VVisPrim: public G4Visible {
friend ostream& operator << (ostream& os, const G4VVisPrim& prim);
public:
G4VVisPrim ();
G4VVisPrim (const G4VVisPrim& prim);
G4VVisPrim& operator = (const G4VVisPrim& right);
G4VVisPrim (const G4VisAttributes* pVA);
virtual G4bool operator == (const G4VVisPrim& prim) const;
};
#include "G4VVisPrim.icc"
#endif
@@ -0,0 +1,32 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VVisPrim.icc,v 2.0 1998/07/02 17:30:24 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison August 1995
inline G4VVisPrim::G4VVisPrim () {}
inline G4VVisPrim::G4VVisPrim (const G4VVisPrim& prim):
G4Visible (prim)
{}
inline G4VVisPrim& G4VVisPrim::operator = (const G4VVisPrim& right) {
((G4Visible*) this) -> operator = (right);
return *this;
}
inline G4VVisPrim::G4VVisPrim (const G4VisAttributes* pVA):
G4Visible (pVA)
{}
inline G4bool G4VVisPrim::operator == (const G4VVisPrim& prim) const{
return this == &prim;
}
@@ -0,0 +1,82 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VisAttributes.hh,v 2.2 1998/11/25 16:01:15 allison Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 23rd October 1996
#ifndef __G4VISATTRIBUTES_HH__
#define __G4VISATTRIBUTES_HH__
#include "G4ios.hh"
#include "globals.hh"
#include "G4Colour.hh"
#include "G4Color.hh"
class G4VisAttributes {
friend ostream& operator << (ostream& os, const G4VisAttributes& a);
friend G4bool operator != (const G4VisAttributes& a1,
const G4VisAttributes& a2);
public:
// Constructors, etc. - begin snippet.
enum LineStyle {unbroken, dashed, dotted};
enum ForcedDrawingStyle {wireframe, solid};
G4VisAttributes ();
G4VisAttributes (G4bool visibility);
G4VisAttributes (const G4Colour& colour);
G4VisAttributes (G4bool visibility, const G4Colour& colour);
static const G4VisAttributes Invisible;
// Constructors - end snippet.
G4bool IsVisible () const;
G4bool IsDaughtersInvisible () const;
const G4Colour& GetColour () const;
const G4Color& GetColor () const;
LineStyle GetLineStyle () const;
G4double GetLineWidth () const;
G4bool IsForceDrawingStyle () const;
ForcedDrawingStyle GetForcedDrawingStyle () const;
// Set methods - begin snippet.
void SetVisibility (G4bool);
void SetDaughtersInvisible (G4bool);
void SetColour (const G4Colour&);
void SetColor (const G4Color&);
void SetColour (G4double red, G4double green, G4double blue,
G4double alpha = 1.);
void SetColor (G4double red, G4double green, G4double blue,
G4double alpha = 1.);
void SetLineStyle (LineStyle);
void SetLineWidth (G4double);
void SetForceWireframe (G4bool);
void SetForceSolid (G4bool);
// Set methods - end snippet.
private:
// Available attributes - begin snippet.
G4bool fVisible; // Visibility flag
G4bool fDaughtersInvisible; // Make daughters invsibile.
G4Colour fColour;
LineStyle fLineStyle;
G4double fLineWidth; // Units of "normal" device linewidth, e.g.,
// pixels for screen, 0.1 mm for paper.
G4bool fForceDrawingStyle; // To override view parameters.
ForcedDrawingStyle fForcedStyle;
// Available attributes - end snippet.
};
#include "G4VisAttributes.icc"
#endif
@@ -0,0 +1,80 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VisAttributes.icc,v 2.1 1998/11/25 16:01:18 allison Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 18th November 1996
inline G4bool G4VisAttributes::IsVisible () const {return fVisible;}
inline G4bool G4VisAttributes::IsDaughtersInvisible () const {
return fDaughtersInvisible;
}
inline const G4Colour& G4VisAttributes::GetColour () const {return fColour;}
inline const G4Color& G4VisAttributes::GetColor () const {return fColour;}
inline G4VisAttributes::LineStyle G4VisAttributes::GetLineStyle () const {
return fLineStyle;
}
inline G4double G4VisAttributes::GetLineWidth () const {
return fLineWidth;
}
inline G4bool G4VisAttributes::IsForceDrawingStyle () const {
return fForceDrawingStyle;
}
inline G4VisAttributes::ForcedDrawingStyle
G4VisAttributes::GetForcedDrawingStyle () const {
return fForcedStyle;
}
inline void G4VisAttributes::SetVisibility (G4bool v) {fVisible = v;}
inline void G4VisAttributes::SetDaughtersInvisible (G4bool v) {
fDaughtersInvisible = v;
}
inline void G4VisAttributes::SetColour (const G4Colour& colour) {
fColour = colour;
}
inline void G4VisAttributes::SetColor (const G4Color& color) {
fColour = color;
}
inline void G4VisAttributes::SetColour
(G4double red, G4double green, G4double blue, G4double alpha) {
fColour = G4Colour (red, green, blue, alpha);
}
inline void G4VisAttributes::SetColor
(G4double red, G4double green, G4double blue, G4double alpha) {
fColour = G4Color (red, green, blue, alpha);
}
inline void G4VisAttributes::SetLineStyle (G4VisAttributes::LineStyle style) {
fLineStyle = style;
}
inline void G4VisAttributes::SetLineWidth (G4double w) {
fLineWidth = w;
}
inline void G4VisAttributes::SetForceWireframe (G4bool force) {
fForceDrawingStyle = force;
fForcedStyle = G4VisAttributes::wireframe;
}
inline void G4VisAttributes::SetForceSolid (G4bool force) {
fForceDrawingStyle = force;
fForcedStyle = G4VisAttributes::solid;
}
@@ -0,0 +1,71 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VisExtent.hh,v 2.0 1998/07/02 17:30:29 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// A.Walkden 28/11/95
// VisExtent.hh, header file to prototype Extent functions for use in
// instantiating Visualisation windows with an appropriate field of
// view for the object(s) being drawn.
#ifndef G4VISEXTENT_HH
#define G4VISEXTENT_HH
#include "globals.hh"
#include "G4Point3D.hh"
class G4VisExtent
{
public:
G4VisExtent (G4double xmin = 0., G4double xmax = 0.,
G4double ymin = 0., G4double ymax = 0.,
G4double zmin = 0., G4double zmax = 0.);
G4VisExtent (const G4Point3D& centre, G4double radius);
~G4VisExtent ();
G4double GetXmin () const;
G4double GetXmax () const;
G4double GetYmin () const;
G4double GetYmax () const;
G4double GetZmin () const;
G4double GetZmax () const;
G4Point3D GetExtentCentre () const;
G4Point3D GetExtentCenter () const;
G4double GetExtentRadius () const;
void SetXmin (G4double xmin);
void SetXmax (G4double xmax);
void SetYmin (G4double ymin);
void SetYmax (G4double ymax);
void SetZmin (G4double zmin);
void SetZmax (G4double zmax);
friend ostream& operator << (ostream& os, const G4VisExtent& e);
friend G4bool operator != (const G4VisExtent& e1, const G4VisExtent& e2);
private:
G4double fXmin, fXmax, fYmin, fYmax, fZmin, fZmax;
};
inline G4double G4VisExtent::GetXmin () const { return fXmin; }
inline G4double G4VisExtent::GetXmax () const { return fXmax; }
inline G4double G4VisExtent::GetYmin () const { return fYmin; }
inline G4double G4VisExtent::GetYmax () const { return fYmax; }
inline G4double G4VisExtent::GetZmin () const { return fZmin; }
inline G4double G4VisExtent::GetZmax () const { return fZmax; }
inline G4Point3D G4VisExtent::GetExtentCenter () const {
return GetExtentCentre ();
}
inline void G4VisExtent::SetXmin (G4double xmin) {fXmin = xmin;}
inline void G4VisExtent::SetXmax (G4double xmax) {fXmax = xmax;}
inline void G4VisExtent::SetYmin (G4double ymin) {fYmin = ymin;}
inline void G4VisExtent::SetYmax (G4double ymax) {fYmax = ymax;}
inline void G4VisExtent::SetZmin (G4double zmin) {fZmin = zmin;}
inline void G4VisExtent::SetZmax (G4double zmax) {fZmax = zmax;}
#endif
+48
View File
@@ -0,0 +1,48 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Visible.hh,v 2.0 1998/07/02 17:30:32 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 30th October 1996
// Base class for all things visible, i.e., which have Vis Attributes.
// Note: a null pointer implies no attributes. Under those circumstances
// the visualization system is free to choose some.
#ifndef G4VISIBLE_HH
#define G4VISIBLE_HH
class G4VisAttributes;
class ostream;
class G4Visible {
friend ostream& operator << (ostream& os, const G4Visible& v);
public:
G4Visible ();
G4Visible (const G4Visible& visible);
G4Visible& operator = (const G4Visible& right);
G4Visible (const G4VisAttributes* pVA);
const G4VisAttributes* GetVisAttributes () const;
void SetVisAttributes (const G4VisAttributes* pVA);
void SetVisAttributes (const G4VisAttributes& VA);
protected:
const G4VisAttributes* fpVisAttributes;
};
#include "G4Visible.icc"
#endif
@@ -0,0 +1,39 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Visible.icc,v 2.0 1998/07/02 17:30:38 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 30th October 1996
inline G4Visible::G4Visible (): fpVisAttributes (0) {}
inline G4Visible::G4Visible (const G4Visible& visible):
fpVisAttributes (visible.fpVisAttributes)
{}
inline G4Visible& G4Visible::operator = (const G4Visible& right) {
fpVisAttributes = right.fpVisAttributes;
return *this;
}
inline G4Visible::G4Visible (const G4VisAttributes* pVA):
fpVisAttributes (pVA)
{}
inline const G4VisAttributes* G4Visible::GetVisAttributes () const {
return fpVisAttributes;
}
inline void G4Visible::SetVisAttributes (const G4VisAttributes* pVA) {
fpVisAttributes = pVA;
}
inline void G4Visible::SetVisAttributes (const G4VisAttributes& VA) {
fpVisAttributes = &VA;
}
+31
View File
@@ -0,0 +1,31 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Colour.cc,v 2.1 1998/07/13 16:56:14 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 20th October 1996
#include "G4Colour.hh"
#include "G4ios.hh"
ostream& operator << (ostream& os, const G4Colour& c) {
return os << '(' << c.red << ',' << c.green << ',' << c.blue
<< ',' << c.alpha << ')';
}
G4bool operator != (const G4Colour& c1, const G4Colour& c2) {
if (
(c1.red != c2.red) ||
(c1.green != c2.green) ||
(c1.blue != c2.blue) ||
(c1.alpha != c2.alpha)
)
return true;
return false;
}
+735
View File
@@ -0,0 +1,735 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4NURBS.cc,v 2.3 1998/12/01 13:36:42 evc Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// Olivier Crumeyrolle 12 September 1996
// G4NURBS.cc
// Implementation of class G4NURBS
// OC 100796
#include "G4NURBS.hh"
// G4NURBS.hh includes globals.hh which includes a lot of others
// so no more includes required here
// stdlib required for the exit function
//#include <stdlib.h>
// memcpy
//#include <string.h>
////////////////////////////////////////////////////////////////////////
// Here start the real world. Please, check your armored jacket. //
////////////////////////////////////////////////////////////////////////
ostream & operator << (ostream & inout_outStream, const G4NURBS & in_kNurb)
{
inout_outStream
// the magic could be changed for good reasons only
<< "##ojc{NURBS}def[1.01.96.7] Just a magic. Could be added to /etc/magic"
<< "\n# NURBS Definition File (human and computer readable format)"
<< "\n# :" << in_kNurb.Whoami()
<< "\n# U order\tV order : "
<< '\n' << in_kNurb.GetUorder() << "\t\t" << in_kNurb.GetVorder();
// number of knots and knots themselves for U and V
for (G4NURBS::t_direction dir = G4NURBS::U; dir < G4NURBS::NofD; /*(*(int *)(&dir))++*/ dir=(G4NURBS::t_direction)(((int)(dir))+1) )
{
inout_outStream
<< "\n# Number of knots along " << G4NURBS::Tochar(dir)
<< '\n' << in_kNurb.GetnbrKnots(dir)
<< "\n# " << G4NURBS::Tochar(dir) << " knots vector (as a column)";
{ // begin knots iteration
G4double oneKnot;
G4NURBS::KnotsIterator knotI(in_kNurb,dir);
G4bool otherKnots;
do
{
otherKnots = knotI.pick(&oneKnot);
inout_outStream << "\n\t\t" << oneKnot;
}
while (otherKnots);
} // end of knots iteration
}; // end of direction loop
// number of control points in U and V direction
// and controlpoints
inout_outStream
<< "\n# Number of control points along U and V"
<< '\n' << in_kNurb.GetUnbrCtrlPts()
<< " " << in_kNurb.GetVnbrCtrlPts()
<< "\n# Control Points (one by line, U increasing first)";
{ // begin of control points iteration
G4NURBS::t_doubleCtrlPt oneCP;
G4NURBS::CtrlPtsIterator cpI(in_kNurb);
G4bool otherCPs;
do
{
otherCPs = cpI.pick(&oneCP);
inout_outStream
<< "\n\t" << oneCP[G4NURBS::X]
<< "\t" << oneCP[G4NURBS::Y]
<< "\t" << oneCP[G4NURBS::Z]
<< "\t" << oneCP[G4NURBS::W];
}
while (otherCPs);
} // end of control point iteration
inout_outStream << "\n# That's all!" << endl; // endl do an \n and a flush
return inout_outStream;
}
// the CC compiler issue some "maybe no value returned"
// but everything is ok
G4float G4NURBS::GetfloatKnot(t_direction in_dir, t_indKnot in_index) const
{
in_dir = (t_direction)(in_dir & DMask);
if ( in_index < m[in_dir].nbrKnots )
return ((G4float)(m[in_dir].pKnots[in_index]));
else
{
G4cerr << "\nERROR: G4NURBS::GetfloatKnot: index out of range\n"
<< "\n\t in_dir : " << in_dir << ", in_index : " << in_index
<< "m[in_dir].nbrKnots : " << m[in_dir].nbrKnots << endl;
return ((G4float)m[in_dir].pKnots[m[in_dir].nbrKnots-1]);
};
}
G4double G4NURBS::GetdoubleKnot(t_direction in_dir, t_indKnot in_index) const
{
in_dir = (t_direction)(in_dir & DMask);
if ( in_index < m[in_dir].nbrKnots )
return (G4double)(m[in_dir].pKnots[in_index]);
else
{
G4cerr << "\nERROR: G4NURBS::GetdoubleKnot: index out of range"
<< "\n\t in_dir : " << in_dir << ", in_index : " << in_index
<< "m[in_dir].nbrKnots : " << m[in_dir].nbrKnots << endl;
return (G4double)(m[in_dir].pKnots[m[in_dir].nbrKnots-1]);
};
}
G4NURBS::t_floatCtrlPt* G4NURBS::GetfloatCtrlPt(t_indCtrlPt in_onedimindex) const
{
if (in_onedimindex < mtotnbrCtrlPts)
return TofloatCtrlPt(mpCtrlPts[in_onedimindex]);
else
{
G4cerr << "\nERROR: G4NURBS::GetfloatCtrlPt: index out of range"
<< "\n\t in_onedimindex : " << in_onedimindex
<< " , mtotnbrCtrlPts : " << mtotnbrCtrlPts << endl;
return TofloatCtrlPt(mpCtrlPts[mtotnbrCtrlPts-1]);
};
}
G4NURBS::t_floatCtrlPt* G4NURBS::GetfloatCtrlPt(t_inddCtrlPt in_Uindex, t_inddCtrlPt in_Vindex) const
{
if (
(in_Uindex < m[U].nbrCtrlPts)
&& (in_Vindex < m[V].nbrCtrlPts)
)
return TofloatCtrlPt(mpCtrlPts[To1d(in_Uindex, in_Vindex)]);
else
{
G4cerr << "\nERROR: G4NURBS::GetfloatCtrlPt: index(s) out of range"
<< "\n\t in_Uindex : " << in_Uindex
<< " , in_Vindex : " << in_Vindex
<< " , UnbrCtrlPts : " << m[U].nbrCtrlPts
<< " , VnbrCtrlPts : " << m[V].nbrCtrlPts << endl;
return TofloatCtrlPt(mpCtrlPts[mtotnbrCtrlPts-1]);
};
}
G4NURBS::t_doubleCtrlPt* G4NURBS::GetdoubleCtrlPt(t_indCtrlPt in_onedimindex) const
{
if ( in_onedimindex < mtotnbrCtrlPts )
return TodoubleCtrlPt(mpCtrlPts[in_onedimindex]);
else
{
G4cerr << "\nERROR: G4NURBS::getdoubleCtrlPts: index out of range"
<< "\n\t in_onedimindex : " << in_onedimindex
<< " , mtotnbrCtrlPts : " << mtotnbrCtrlPts << endl;
return TodoubleCtrlPt(mpCtrlPts[mtotnbrCtrlPts-1]);
};
}
G4NURBS::t_doubleCtrlPt* G4NURBS::GetdoubleCtrlPt(t_inddCtrlPt in_Uindex, t_inddCtrlPt in_Vindex) const
{
if (
(in_Uindex < m[U].nbrCtrlPts)
&& (in_Vindex < m[V].nbrCtrlPts)
)
return TodoubleCtrlPt(mpCtrlPts[To1d(in_Uindex, in_Vindex)]);
else
{
G4cerr << "\nERROR: G4NURBS::GetdoubleCtrlPt: index(s) out of range"
<< "\n\t in_Uindex : " << in_Uindex
<< " , in_Vindex : " << in_Vindex
<< " , UnbrCtrlPts : " << m[U].nbrCtrlPts
<< " , VnbrCtrlPts : " << m[V].nbrCtrlPts << endl;
return TodoubleCtrlPt(mpCtrlPts[mtotnbrCtrlPts-1]);
};
}
// Total copy
G4float * G4NURBS::GetfloatAllKnots(t_direction in_dir) const
{
in_dir = (t_direction)(in_dir & DMask);
G4float * p = new G4float [m[in_dir].nbrKnots];
for (t_indKnot i = 0; i < m[in_dir].nbrKnots; i++)
p[i] = (G4float)m[in_dir].pKnots[i];
return p;
}
G4double * G4NURBS::GetdoubleAllKnots(t_direction in_dir) const
{
in_dir = (t_direction)(in_dir & DMask);
G4double * p = new G4double [m[in_dir].nbrKnots];
for (t_indKnot i = 0; i < m[in_dir].nbrKnots; i++)
p[i] = (G4double)m[in_dir].pKnots[i];
return p;
}
G4float * G4NURBS::GetfloatAllCtrlPts() const
{
G4float * p = new G4float [mtotnbrCtrlPts*NofC];
for (t_indKnot i = 0; i < mtotnbrCtrlPts*NofC; i++)
p[i] = (G4float)(((t_Coord *)mpCtrlPts)[i]);
return p;
}
G4double * G4NURBS::GetdoubleAllCtrlPts() const
{
G4double * p = new G4double [mtotnbrCtrlPts*NofC];
for (t_indKnot i = 0; i < mtotnbrCtrlPts*NofC; i++)
p[i] = (G4double)(((t_Coord *)mpCtrlPts)[i]);
return p;
}
// Iterators
G4NURBS::KnotsIterator::KnotsIterator(const G4NURBS & in_rNurb, G4NURBS::t_direction in_dir, t_indKnot in_startIndex)
: kmdir((G4NURBS::t_direction)(in_dir & G4NURBS::DMask)),
kmpMax(in_rNurb.m[kmdir].pKnots + in_rNurb.m[kmdir].nbrKnots)
{
if (in_startIndex < in_rNurb.m[kmdir].nbrKnots)
mp = in_rNurb.m[kmdir].pKnots + in_startIndex;
else
{
G4cerr << "\nERROR: G4NURBS::KnotsIterator: in_startIndex out of range"
<< "\n\tin_startIndex : " << in_startIndex
<< ", nbr of knots : " << in_rNurb.m[kmdir].nbrKnots
<< "\n\t mp set to NULL, calls to picking functions will fail"
<< endl;
mp = NULL;
};
}
G4bool G4NURBS::KnotsIterator::pick(G4double * inout_pDbl)
{
(*inout_pDbl) = (G4double)(*mp);
return (G4bool)((++mp)<kmpMax);
}
G4bool G4NURBS::KnotsIterator::pick(G4float * inout_pFlt)
{
(*inout_pFlt) = (G4float)(*mp);
return (G4bool)((++mp)<kmpMax);
}
G4NURBS::CtrlPtsCoordsIterator::CtrlPtsCoordsIterator(const G4NURBS & in_rNurb, t_indCtrlPt in_startCtrlPtIndex)
: kmpMax((const t_Coord *)(in_rNurb.mpCtrlPts + in_rNurb.mtotnbrCtrlPts))
{
if (in_startCtrlPtIndex < in_rNurb.mtotnbrCtrlPts )
mp = (const t_Coord *)(in_rNurb.mpCtrlPts + in_startCtrlPtIndex);
else
{
G4cerr << "\nERROR: G4NURBS::CtrlPtsCoordsIterator: in_startCtrlPtIndex out of range"
<< "\n\tin_startCtrlPtIndex : " << in_startCtrlPtIndex
<< ", nbr of CtrlPts : " << in_rNurb.mtotnbrCtrlPts
<< "\n\t mp set to NULL, calls to picking functions will fail"
<< endl;
mp = NULL;
};
}
G4bool G4NURBS::CtrlPtsCoordsIterator::pick(G4double * inout_pDbl)
{
(*inout_pDbl) = (G4double)((*mp));
return (G4bool)((++mp)<kmpMax);
}
G4bool G4NURBS::CtrlPtsCoordsIterator::pick(G4float * inout_pFlt)
{
(*inout_pFlt) = (G4float)((*mp));
return (G4bool)((++mp)<kmpMax);
}
G4NURBS::CtrlPtsIterator::CtrlPtsIterator(const G4NURBS & in_rNurb, t_indCtrlPt in_startIndex)
: kmpMax(in_rNurb.mpCtrlPts + in_rNurb.mtotnbrCtrlPts)
{
if (in_startIndex < in_rNurb.mtotnbrCtrlPts )
mp = (in_rNurb.mpCtrlPts + in_startIndex);
else
{
G4cerr << "\nERROR: G4NURBS::CtrlPtsIterator: in_startIndex out of range"
<< "\n\tin_startIndex : " << in_startIndex
<< ", nbr of CtrlPts : " << in_rNurb.mtotnbrCtrlPts
<< "\n\t mp set to NULL, calls to picking functions will fail"
<< endl;
mp = NULL;
};
}
G4bool G4NURBS::CtrlPtsIterator::pick(t_doubleCtrlPt * inout_pDblCtrlPt)
{
for (t_indCoord i = G4NURBS::X; i < G4NURBS::NofC; i++)
(*inout_pDblCtrlPt)[i] = (G4double)((*mp)[i]);
return (G4bool)((++mp)<kmpMax);
}
G4bool G4NURBS::CtrlPtsIterator::pick(t_floatCtrlPt * inout_pFltCtrlPt)
{
for (t_indCoord i = G4NURBS::X; i < G4NURBS::NofC; i++)
(*inout_pFltCtrlPt)[i] = (G4float)((*mp)[i]);
return (G4bool)((++mp)<kmpMax);
}
////////////////////////////////////////////////////////////////////////
// Building functions
G4bool G4NURBS::MakeKnotVector(t_Dir & io_d, t_KnotVectorGenFlag in_KVGFlag)
{
G4bool isgood = (io_d.order + io_d.nbrCtrlPts == io_d.nbrKnots)
&& (io_d.pKnots == NULL);
if ( isgood )
{
io_d.pKnots = new t_Knot [io_d.nbrKnots];
if (in_KVGFlag != UserDefined)
{ // let's do the knots
t_indKnot indKnot = 0;
t_index nbrCentralDistinctKnots = io_d.nbrCtrlPts-io_d.order;
if ( (nbrCentralDistinctKnots % in_KVGFlag) == 0)
{
nbrCentralDistinctKnots /= in_KVGFlag;
// first and last knots repeated 'order' Times
for (t_index i=0; i < io_d.order; indKnot++,i++)
{
io_d.pKnots[indKnot] = 0;
io_d.pKnots[indKnot+io_d.nbrCtrlPts] = 1;
};
t_Knot stepKnot = 1.0/(t_Knot)(nbrCentralDistinctKnots+1);
t_Knot valKnot = stepKnot;
// central knots
for (t_indKnot j=0; j < nbrCentralDistinctKnots; valKnot += stepKnot, j++)
{
for (t_indKnot k=0; k < in_KVGFlag; indKnot++, k++)
io_d.pKnots[indKnot] = valKnot;
};
}
else isgood = false;
}; // end of knots making
};
return isgood;
}
ostream & operator << (ostream & io_ostr, G4NURBS::t_KnotVectorGenFlag in_f)
{
switch (in_f)
{
case G4NURBS::UserDefined: io_ostr << "UserDefined"; break;
case G4NURBS::Regular: io_ostr << "Regular"; break;
case G4NURBS::RegularRep: io_ostr << "RegularRep"; break;
default: io_ostr << (int)in_f;
};
return io_ostr;
}
////////////////////////////////////////////////////////////////////////
// Constructors and co
void G4NURBS::Conscheck() const
{
G4int dummy;
t_direction dir;
for (dummy=0; (dummy?(dir=V):(dir=U)),(dummy < NofD); dummy++)
{
if (m[dir].order<=0)
{
G4cerr << "\nFATAL ERROR: G4NURBS::G4NURBS: The order in the "
<< G4NURBS::Tochar(dir)
<< " direction must be >= 1" << endl;
exit(-1);
};
if (m[dir].nbrCtrlPts<=0)
{
G4cerr << "\nFATAL ERROR: G4NURBS::G4NURBS: The number of control points "
<< G4NURBS::Tochar(dir)
<< " direction must be >= 1" << endl;
exit(-1);
};
}; // end of dummy
}
G4NURBS::G4NURBS
(
t_order in_Uorder, t_order in_Vorder,
t_inddCtrlPt in_UnbrCtrlPts, t_inddCtrlPt in_VnbrCtrlPts,
t_CtrlPt * in_pCtrlPts,
t_Knot * in_pUKnots, t_Knot * in_pVKnots,
t_CheckFlag in_CheckFlag
)
{
m[U].order=in_Uorder; m[V].order=in_Vorder;
m[U].nbrCtrlPts=in_UnbrCtrlPts; m[V].nbrCtrlPts=in_VnbrCtrlPts;
mtotnbrCtrlPts = m[U].nbrCtrlPts * m[V].nbrCtrlPts;
m[U].nbrKnots = m[U].order + m[U].nbrCtrlPts;
m[V].nbrKnots = m[V].order + m[V].nbrCtrlPts;
if (in_CheckFlag)
Conscheck();
// CtrlPts
if (! (mpCtrlPts = in_pCtrlPts) )
{
G4cerr << "\nFATAL ERROR: G4NURBS::G4NURBS: A NURBS MUST HAVE CONTROL POINTS!\n\teven if they are defined later, the array must be allocated."
<< "\n\tgood bye. Have a nice debuging." << endl;
exit(-1);
};
//mnbralias = 0;
// Knots
t_direction dir;
G4int dummy;
for (dummy=0; (dummy?(dir=V):(dir=U)),(dummy < NofD); dummy++)
{
if ( !(m[dir].pKnots = (dummy?in_pVKnots:in_pUKnots)) )
{ // make some regular knots between 0 & 1
if(!MakeKnotVector(m[dir], Regular))
{
G4cerr << "\nFATAL ERROR: G4NURBS::G4NURBS: Unable to make a Regular knot vector along "
<< G4NURBS::Tochar(dir)
<< " direction."
<< "\n\tgood bye. Have a nice debuging."
<< endl;
exit(-1);
};
//m[dir].nbralias = 0;
}; // end of knots-making
};// end for dummy
} // end of G4NURBS::G4NURBS
// second constructor
G4NURBS::G4NURBS(
t_order in_Uorder, t_order in_Vorder,
t_inddCtrlPt in_UnbrCtrlPts, t_inddCtrlPt in_VnbrCtrlPts,
t_KnotVectorGenFlag in_UKVGFlag,
t_KnotVectorGenFlag in_VKVGFlag,
t_CheckFlag in_CheckFlag
)
{
m[U].order=in_Uorder; m[V].order=in_Vorder;
m[U].nbrCtrlPts=in_UnbrCtrlPts; m[V].nbrCtrlPts=in_VnbrCtrlPts;
mtotnbrCtrlPts = m[U].nbrCtrlPts * m[V].nbrCtrlPts;
m[U].nbrKnots = m[U].order + m[U].nbrCtrlPts;
m[V].nbrKnots = m[V].order + m[V].nbrCtrlPts;
if (in_CheckFlag)
Conscheck();
// Allocate CtrlPts
mpCtrlPts = new t_CtrlPt [mtotnbrCtrlPts];
//mnbralias = 0;
// Knots
t_direction dir;
G4int dummy;
for (dummy=0; (dummy?(dir=V):(dir=U)),(dummy < NofD); dummy++)
{
t_KnotVectorGenFlag flag = (dummy?in_VKVGFlag:in_UKVGFlag);
m[dir].pKnots = NULL; // (allocation under our control)
if ( flag && !MakeKnotVector(m[dir], flag) )
{
G4cerr << "\nFATAL ERROR: G4NURBS::G4NURBS: Unable to make knot vector along "
<< G4NURBS::Tochar(dir)
<< " direction. (" << m[dir].nbrKnots
<< " knots requested for a "
<< flag
<< " knots vector)"
<< "\n\tgood bye. Have a nice debuging."
<< endl;
exit(-1);
};
//m[dir].nbralias = 0;
};
}
G4NURBS::G4NURBS(const G4NURBS & in_krNurb)
{
// we assume the in nurbs is ok
// the number of CtrlPts can be copied straightly
mtotnbrCtrlPts = in_krNurb.mtotnbrCtrlPts;
// the main datas
// but as m is an array of t_Dir and as t_Dir
// is just a structure and not a class with a copy cons
// whe need to duplicate the knots
t_direction dir;
G4int dummy;
for (dummy=0; (dummy?(dir=V):(dir=U)),(dummy < NofD); dummy++)
{
// first we do a 'stupid' copy of m[dir]
m[dir] = in_krNurb.m[dir];
// but as m is an array of t_Dir and as t_Dir
// is just a structure and not a class with a copy cons
// whe need to duplicate the knots
m[dir].pKnots = new G4double [m[dir].nbrKnots];
// we copy the knots with memcpy. This function should be the fastest
memcpy(m[dir].pKnots, in_krNurb.m[dir].pKnots, m[dir].nbrKnots * sizeof(G4double));
}; // end of dummy loop
// the control points
// once again we need to do the copy
mpCtrlPts = new t_CtrlPt [mtotnbrCtrlPts];
memcpy(mpCtrlPts, in_krNurb.mpCtrlPts, mtotnbrCtrlPts*sizeof(t_CtrlPt));
// and as it's very strange to copy a nurbs in G4
// we issue a warning :
G4cerr << "\nWARNING: G4NURBS::G4NURBS(const G4NURBS &) used" << endl;
} // end of G4NURBS::G4NURBS(const G4NURBS &)
G4NURBS::~G4NURBS()
{
// we must free the two knots vector
t_direction dir;
G4int dummy;
for (dummy=0; (dummy?(dir=V):(dir=U)),(dummy < NofD); dummy++)
{
if (m[dir].pKnots)
delete m[dir].pKnots; // [m[dir].nbrKnots] if t_Knot become a class
m[dir].pKnots = NULL;
};
// now we free the CtrlPts array
if (mpCtrlPts)
delete [] mpCtrlPts; // [mtotnbrCtrlPts] if t_CtrlPt become a class
mpCtrlPts = NULL;
}
/************************************************************************
* *
* Return the current knot the parameter u is less than or equal to. *
* Find this "breakpoint" allows the evaluation routines to concentrate *
* on only those control points actually effecting the curve around u.] *
* *
* m is the number of points on the curve (or surface direction) *
* k is the order of the curve (or surface direction) *
* kv is the knot vector ([0..m+k-1]) to find the break point in. *
* *
************************************************************************/
static int FindBreakPoint(double u, const Float *kv, int m, int k)
{
int i;
if (u == kv[m+1]) return m; /* Special case for closed interval */
i = m + k;
while ((u < kv[i]) && (i > 0)) i--;
return(i);
}
/************************************************************************
* *
* Compute Bi,k(u), for i = 0..k. *
* u the parameter of the spline to find the basis functions for*
* brkPoint the start of the knot interval ("segment") *
* kv the knot vector *
* k the order of the curve *
* bvals the array of returned basis values. *
* *
* (From Bartels, Beatty & Barsky, p.387) *
* *
************************************************************************/
static void BasisFunctions(double u, int brkPoint,
const Float *kv, int k, double *bvals)
{
int r, s, i;
double omega;
bvals[0] = 1.0;
for (r=2; r <= k; r++) {
i = brkPoint - r + 1;
bvals[r-1] = 0.0;
for (s=r-2; s >= 0; s--) {
i++;
if (i < 0) {
omega = 0.0;
}else{
omega = (u - kv[i]) / (kv[i+r-1] - kv[i]);
}
bvals[s+1] = bvals[s+1] + (1.0-omega) * bvals[s];
bvals[s] = omega * bvals[s];
}
}
}
/************************************************************************
* *
* Compute derivatives of the basis functions Bi,k(u)' *
* *
************************************************************************/
static void BasisDerivatives(double u, int brkPoint,
const Float *kv, int k, double *dvals)
{
int s, i;
double omega, knotScale;
BasisFunctions(u, brkPoint, kv, k-1, dvals);
dvals[k-1] = 0.0; /* BasisFunctions misses this */
knotScale = kv[brkPoint+1] - kv[brkPoint];
i = brkPoint - k + 1;
for (s=k-2; s >= 0; s--) {
i++;
omega = knotScale * ((double)(k-1)) / (kv[i+k-1] - kv[i]);
dvals[s+1] += -omega * dvals[s];
dvals[s] *= omega;
}
}
/***********************************************************************
* *
* Calculate a point p on NurbSurface n at a specific u, v *
* using the tensor product. *
* *
* Note the valid parameter range for u and v is *
* (kvU[orderU] <= u < kvU[numU), (kvV[orderV] <= v < kvV[numV]) *
* *
***********************************************************************/
void G4NURBS::CalcPoint(double u, double v, G4Point3D &p,
G4Vector3D &utan, G4Vector3D &vtan) const
{
#define MAXORDER 50
struct Point4 {
double x, y, z, w;
};
int i, j, ri, rj;
int ubrkPoint, ufirst;
double bu[MAXORDER], buprime[MAXORDER];
int vbrkPoint, vfirst;
double bv[MAXORDER], bvprime[MAXORDER];
Point4 r, rutan, rvtan;
r.x = 0.0; r.y = 0.0; r.z = 0.0; r.w = 0.0;
rutan = r; rvtan = r;
int numU = GetUnbrCtrlPts();
int numV = GetVnbrCtrlPts();
int orderU = GetUorder();
int orderV = GetVorder();
/* Evaluate non-uniform basis functions (and derivatives) */
ubrkPoint = FindBreakPoint(u, m[U].pKnots, numU-1, orderU);
ufirst = ubrkPoint - orderU + 1;
BasisFunctions (u, ubrkPoint, m[U].pKnots, orderU, bu);
BasisDerivatives(u, ubrkPoint, m[U].pKnots, orderU, buprime);
vbrkPoint = FindBreakPoint(v, m[V].pKnots, numV-1, orderV);
vfirst = vbrkPoint - orderV + 1;
BasisFunctions (v, vbrkPoint, m[V].pKnots, orderV, bv);
BasisDerivatives(v, vbrkPoint, m[V].pKnots, orderV, bvprime);
/* Weight control points against the basis functions */
t_doubleCtrlPt *cpoint;
Point4 cp;
double tmp;
for (i=0; i<orderV; i++) {
for (j=0; j<orderU; j++) {
ri = orderV - 1 - i;
rj = orderU - 1 - j;
tmp = bu[rj] * bv[ri];
cpoint = GetdoubleCtrlPt(j+ufirst, i+vfirst);
cp.x = *cpoint[G4NURBS::X];
cp.y = *cpoint[G4NURBS::Y];
cp.z = *cpoint[G4NURBS::Z];
cp.w = *cpoint[G4NURBS::W];
r.x += cp.x * tmp;
r.y += cp.y * tmp;
r.z += cp.z * tmp;
r.w += cp.w * tmp;
tmp = buprime[rj] * bv[ri];
rutan.x += cp.x * tmp;
rutan.y += cp.y * tmp;
rutan.z += cp.z * tmp;
rutan.w += cp.w * tmp;
tmp = bu[rj] * bvprime[ri];
rvtan.x += cp.x * tmp;
rvtan.y += cp.y * tmp;
rvtan.z += cp.z * tmp;
rvtan.w += cp.w * tmp;
}
}
/* Project tangents, using the quotient rule for differentiation */
double wsqrdiv = 1.0 / (r.w * r.w);
utan.setX((r.w * rutan.x - rutan.w * r.x) * wsqrdiv);
utan.setY((r.w * rutan.y - rutan.w * r.y) * wsqrdiv);
utan.setZ((r.w * rutan.z - rutan.w * r.z) * wsqrdiv);
vtan.setX((r.w * rvtan.x - rvtan.w * r.x) * wsqrdiv);
vtan.setY((r.w * rvtan.y - rvtan.w * r.y) * wsqrdiv);
vtan.setZ((r.w * rvtan.z - rvtan.w * r.z) * wsqrdiv);
p.setX(r.x / r.w);
p.setY(r.y / r.w);
p.setZ(r.z / r.w);
}
+71
View File
@@ -0,0 +1,71 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4NURBSbox.cc,v 2.1 1998/07/12 02:59:19 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// Olivier Crumeyrolle 12 September 1996
// Box builder implementation (KidBox)
// OC 060996
#include "G4NURBSbox.hh"
G4NURBSbox::G4NURBSbox(G4double DX, G4double DY, G4double DZ)
:
G4NURBS (
2, 2, // linear along U and V
4, 5 // line with two 90 degrees folds along U
// rectangle along V (3 folds)
)
// let's it Generate regular knots vector
// (note we are calling the second constructor)
{
t_indCtrlPt i = 0;
CP(mpCtrlPts[i++], DX, DY, DZ, 1 );
CP(mpCtrlPts[i++], DX, DY, DZ, 1 );
CP(mpCtrlPts[i++], DX, DY,-DZ, 1 );
CP(mpCtrlPts[i++], DX, DY,-DZ, 1 );
CP(mpCtrlPts[i++], DX, DY, DZ, 1 );
CP(mpCtrlPts[i++],-DX, DY, DZ, 1 );
CP(mpCtrlPts[i++],-DX, DY,-DZ, 1 );
CP(mpCtrlPts[i++], DX, DY,-DZ, 1 );
CP(mpCtrlPts[i++], DX,-DY, DZ, 1 );
CP(mpCtrlPts[i++],-DX,-DY, DZ, 1 );
CP(mpCtrlPts[i++],-DX,-DY,-DZ, 1 );
CP(mpCtrlPts[i++], DX,-DY,-DZ, 1 );
CP(mpCtrlPts[i++], DX,-DY, DZ, 1 );
CP(mpCtrlPts[i++], DX,-DY, DZ, 1 );
CP(mpCtrlPts[i++], DX,-DY,-DZ, 1 );
CP(mpCtrlPts[i++], DX,-DY,-DZ, 1 );
CP(mpCtrlPts[i++], DX, DY, DZ, 1 );
CP(mpCtrlPts[i++], DX, DY, DZ, 1 );
CP(mpCtrlPts[i++], DX, DY,-DZ, 1 );
CP(mpCtrlPts[i++], DX, DY,-DZ, 1 );
}
const char* G4NURBSbox::Whoami() const
{
return "Box (as a folded piece)";
}
+111
View File
@@ -0,0 +1,111 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4NURBScylinder.cc,v 2.1 1998/07/12 02:59:20 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// Olivier Crumeyrolle 12 September 1996
// Cylinder builder implementation
// OC 090796
#include "G4NURBScylinder.hh"
// for sqrt
//#include <math.h>
// math.h included in template.hh included in globals.hh included in
// G4NURBS.hh included in G4NURBScylinder.hh
// the cylinder constructor use the first G4NURBS constructor
// look in G4NURBStube if you want to see how to use the second one.
G4NURBScylinder::G4NURBScylinder(G4double R, G4double DZ)
:
G4NURBS (
2, 3, // linear along U, quadratic along V
4, 9, // half rectangle along U, circle along V
(new t_CtrlPt [ 4 * 9 ]), // the array for CtrlPts
NULL, // the knot vector along U will be generated
(new t_Knot [ 3 + 9 ]) // knot vector for the circle
)
{
// define the V knot vector
m[V].pKnots[ 0] = 0;
m[V].pKnots[ 1] = 0;
m[V].pKnots[ 2] = 0;
m[V].pKnots[ 3] = 0.25;
m[V].pKnots[ 4] = 0.25;
m[V].pKnots[ 5] = 0.5;
m[V].pKnots[ 6] = 0.5;
m[V].pKnots[ 7] = 0.75;
m[V].pKnots[ 8] = 0.75;
m[V].pKnots[ 9] = 1;
m[V].pKnots[10] = 1;
m[V].pKnots[11] = 1;
// define control points
const G4double sr2o2 = sqrt(2.)/2. ;
CP(mpCtrlPts[ 0] , 0, 0, DZ, 1 );
CP(mpCtrlPts[ 1] , R, 0, DZ, 1 );
CP(mpCtrlPts[ 2] , R, 0, -DZ, 1 );
CP(mpCtrlPts[ 3] , 0, 0, -DZ, 1 );
CP(mpCtrlPts[ 4] , 0, 0, DZ, 1 );
CP(mpCtrlPts[ 5] , R, R, DZ, 1 , sr2o2);
CP(mpCtrlPts[ 6] , R, R,-DZ, 1 , sr2o2);
CP(mpCtrlPts[ 7] , 0, 0, -DZ, 1 );
CP(mpCtrlPts[ 8] , 0, 0, DZ, 1 );
CP(mpCtrlPts[ 9] , 0, R, DZ, 1 );
CP(mpCtrlPts[10] , 0, R, -DZ, 1 );
CP(mpCtrlPts[11] , 0, 0, -DZ, 1 );
CP(mpCtrlPts[12] , 0, 0, DZ, 1 );
CP(mpCtrlPts[13] , -R, R, DZ, 1 , sr2o2);
CP(mpCtrlPts[14] , -R, R,-DZ, 1 , sr2o2);
CP(mpCtrlPts[15] , 0, 0, -DZ, 1 );
CP(mpCtrlPts[16] , 0, 0, DZ, 1 );
CP(mpCtrlPts[17] , -R, 0, DZ, 1 );
CP(mpCtrlPts[18] , -R, 0, -DZ, 1 );
CP(mpCtrlPts[19] , 0, 0, -DZ, 1 );
CP(mpCtrlPts[20] , 0, 0, DZ, 1 );
CP(mpCtrlPts[21] , -R,-R, DZ, 1 , sr2o2);
CP(mpCtrlPts[22] , -R,-R,-DZ, 1 , sr2o2);
CP(mpCtrlPts[23] , 0, 0, -DZ, 1 );
CP(mpCtrlPts[24] , 0, 0, DZ, 1 );
CP(mpCtrlPts[25] , 0, -R, DZ, 1 );
CP(mpCtrlPts[26] , 0, -R,-DZ, 1 );
CP(mpCtrlPts[27] , 0, 0, -DZ, 1 );
CP(mpCtrlPts[28] , 0, 0, DZ, 1 );
CP(mpCtrlPts[29] , R,-R, DZ, 1 , sr2o2);
CP(mpCtrlPts[30] , R,-R,-DZ, 1 , sr2o2);
CP(mpCtrlPts[31] , 0, 0, -DZ, 1 );
CP(mpCtrlPts[32] , 0, 0, DZ, 1 );
CP(mpCtrlPts[33] , R, 0, DZ, 1 );
CP(mpCtrlPts[34] , R, 0, -DZ, 1 );
CP(mpCtrlPts[35] , 0, 0, -DZ, 1 );
}
const char* G4NURBScylinder::Whoami() const
{
return "Cylinder";
}
@@ -0,0 +1,67 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4NURBShexahedron.cc,v 2.1 1998/07/12 02:59:21 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
// hexahedron implementation
// OC 17 9 96
#include "G4NURBShexahedron.hh"
G4NURBShexahedron::G4NURBShexahedron(const G4ThreeVector c [8])
:
G4NURBS (
2, 2, // linear along U and V
5, 4 // Square x polyline
)
// let's it Generate regular knots vector
{
// we need to define control points, indeed
CP(mpCtrlPts[To1d(0,0)] , c[0].x(), c[0].y(), c[0].z(), 1 );
CP(mpCtrlPts[To1d(1,0)] , c[1].x(), c[1].y(), c[1].z(), 1 );
CP(mpCtrlPts[To1d(2,0)] , c[1].x(), c[1].y(), c[1].z(), 1 );
CP(mpCtrlPts[To1d(3,0)] , c[0].x(), c[0].y(), c[0].z(), 1 );
CP(mpCtrlPts[To1d(4,0)] , c[0].x(), c[0].y(), c[0].z(), 1 );
CP(mpCtrlPts[To1d(0,1)] , c[0].x(), c[0].y(), c[0].z(), 1 );
CP(mpCtrlPts[To1d(1,1)] , c[1].x(), c[1].y(), c[1].z(), 1 );
CP(mpCtrlPts[To1d(2,1)] , c[2].x(), c[2].y(), c[2].z(), 1 );
CP(mpCtrlPts[To1d(3,1)] , c[3].x(), c[3].y(), c[3].z(), 1 );
CP(mpCtrlPts[To1d(4,1)] , c[0].x(), c[0].y(), c[0].z(), 1 );
CP(mpCtrlPts[To1d(0,2)] , c[4].x(), c[4].y(), c[4].z(), 1 );
CP(mpCtrlPts[To1d(1,2)] , c[5].x(), c[5].y(), c[5].z(), 1 );
CP(mpCtrlPts[To1d(2,2)] , c[6].x(), c[6].y(), c[6].z(), 1 );
CP(mpCtrlPts[To1d(3,2)] , c[7].x(), c[7].y(), c[7].z(), 1 );
CP(mpCtrlPts[To1d(4,2)] , c[4].x(), c[4].y(), c[4].z(), 1 );
CP(mpCtrlPts[To1d(0,3)] , c[4].x(), c[4].y(), c[4].z(), 1 );
CP(mpCtrlPts[To1d(1,3)] , c[5].x(), c[5].y(), c[5].z(), 1 );
CP(mpCtrlPts[To1d(2,3)] , c[5].x(), c[5].y(), c[5].z(), 1 );
CP(mpCtrlPts[To1d(3,3)] , c[4].x(), c[4].y(), c[4].z(), 1 );
CP(mpCtrlPts[To1d(4,3)] , c[4].x(), c[4].y(), c[4].z(), 1 );
}
const char* G4NURBShexahedron::Whoami() const
{
return "Hexahedron";
}
+101
View File
@@ -0,0 +1,101 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4NURBStube.cc,v 2.1 1998/07/12 02:59:22 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// Olivier Crumeyrolle 12 September 1996
// Tube builder implementation
// OC 090796
#include "G4NURBStube.hh"
// for sqrt
//#include <math.h>
// cf cylinder
G4NURBStube::G4NURBStube(G4double r, G4double R, G4double DZ)
:
G4NURBS (
2, 3, // linear along U, quadratic along V
5, 9, // rectangle along U, circle along V
Regular, // the knot vector along U will be generated
RegularRep // knot vector for the circle also
)
{
// define control points
const G4double sr2o2 = sqrt(2.)/2.;
CP(mpCtrlPts[ 0] , r, 0, DZ, 1 );
CP(mpCtrlPts[ 1] , R, 0, DZ, 1 );
CP(mpCtrlPts[ 2] , R, 0, -DZ, 1 );
CP(mpCtrlPts[ 3] , r, 0, -DZ, 1 );
CP(mpCtrlPts[ 4] , r, 0, DZ, 1 );
CP(mpCtrlPts[ 5] , r, r, DZ, 1 , sr2o2);
CP(mpCtrlPts[ 6] , R, R, DZ, 1 , sr2o2);
CP(mpCtrlPts[ 7] , R, R, -DZ, 1 , sr2o2);
CP(mpCtrlPts[ 8] , r, r, -DZ, 1 , sr2o2);
CP(mpCtrlPts[ 9] , r, r, DZ, 1 , sr2o2);
CP(mpCtrlPts[10] , 0, r, DZ, 1 );
CP(mpCtrlPts[11] , 0, R, DZ, 1 );
CP(mpCtrlPts[12] , 0, R, -DZ, 1 );
CP(mpCtrlPts[13] , 0, r, -DZ, 1 );
CP(mpCtrlPts[14] , 0, r, DZ, 1 );
CP(mpCtrlPts[15] , -r, r, DZ, 1 , sr2o2);
CP(mpCtrlPts[16] , -R, R, DZ, 1 , sr2o2);
CP(mpCtrlPts[17] , -R, R, -DZ, 1 , sr2o2);
CP(mpCtrlPts[18] , -r, r, -DZ, 1 , sr2o2);
CP(mpCtrlPts[19] , -r, r, DZ, 1 , sr2o2);
CP(mpCtrlPts[20] , -r, 0, DZ, 1 );
CP(mpCtrlPts[21] , -R, 0, DZ, 1 );
CP(mpCtrlPts[22] , -R, 0, -DZ, 1 );
CP(mpCtrlPts[23] , -r, 0, -DZ, 1 );
CP(mpCtrlPts[24] , -r, 0, DZ, 1 );
CP(mpCtrlPts[25] , -r,-r, DZ, 1 , sr2o2);
CP(mpCtrlPts[26] , -R,-R, DZ, 1 , sr2o2);
CP(mpCtrlPts[27] , -R,-R, -DZ, 1 , sr2o2);
CP(mpCtrlPts[28] , -r,-r, -DZ, 1 , sr2o2);
CP(mpCtrlPts[29] , -r,-R, DZ, 1 , sr2o2);
CP(mpCtrlPts[30] , 0,-r, DZ, 1 );
CP(mpCtrlPts[31] , 0,-R, DZ, 1 );
CP(mpCtrlPts[32] , 0,-R, -DZ, 1 );
CP(mpCtrlPts[33] , 0,-r, -DZ, 1 );
CP(mpCtrlPts[34] , 0,-r, DZ, 1 );
CP(mpCtrlPts[35] , r,-r, DZ, 1 , sr2o2);
CP(mpCtrlPts[36] , R,-R, DZ, 1 , sr2o2);
CP(mpCtrlPts[37] , R,-R, -DZ, 1 , sr2o2);
CP(mpCtrlPts[38] , r,-r, -DZ, 1 , sr2o2);
CP(mpCtrlPts[39] , r,-r, DZ, 1 , sr2o2);
CP(mpCtrlPts[40] , r, 0, DZ, 1 );
CP(mpCtrlPts[41] , R, 0, DZ, 1 );
CP(mpCtrlPts[42] , R, 0, -DZ, 1 );
CP(mpCtrlPts[43] , r, 0, -DZ, 1 );
CP(mpCtrlPts[44] , r, 0, DZ, 1 );
}
const char* G4NURBStube::Whoami() const
{
return "Tube";
}
@@ -0,0 +1,217 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4NURBStubesector.cc,v 2.2 1998/07/13 16:56:16 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// Olivier Crumeyrolle 12 September 1996
// Tubesector builder implementation
// OC 290896
#include "G4NURBStubesector.hh"
// for sqrt
//#include <math.h>
// cf cylinder
// for ostrstream
#ifdef WIN32
# include <Strstrea.h>
#else
# include <strstream.h>
#endif
G4NURBStubesector::G4NURBStubesector(G4double r, G4double R, G4double DZ, G4double PHI1, G4double PHI2)
:
G4NURBS (
2, 3, // linear along U, quadratic along V
5, DecideNbrCtrlPts(PHI1, PHI2),
// rectangle along U, required stuff along V
// we must use a static function which
// take the two angles because the
// mother constructor is initialised
// before everything
Regular, // the knot vector along U will be generated
RegularRep // circular like knot vector also
)
{
// check angles
G4double deltaPHI = PHI2-PHI1;
while (deltaPHI <= 0) { PHI2 += 2*M_PI; deltaPHI += 2*M_PI; };
G4int f = (int)floor(deltaPHI / (M_PI_2)); //number of pi/2 arcs
const G4double mr = (r+R)/2;
const G4double cp1 = cos(PHI1);
const G4double sp1 = sin(PHI1);
const G4double cp2 = cos(PHI2);
const G4double sp2 = sin(PHI2);
// define control points
CP(mpCtrlPts[ 0] , cp1*mr, sp1*mr, 0, 1 );
CP(mpCtrlPts[ 1] , cp1*mr, sp1*mr, 0, 1 );
CP(mpCtrlPts[ 2] , cp1*mr, sp1*mr, 0, 1 );
CP(mpCtrlPts[ 3] , cp1*mr, sp1*mr, 0, 1 );
CP(mpCtrlPts[ 4] , cp1*mr, sp1*mr, 0, 1 );
CP(mpCtrlPts[ 5] , cp1*mr, sp1*mr, 0, 1 );
CP(mpCtrlPts[ 6] , cp1*mr, sp1*mr, 0, 1 );
CP(mpCtrlPts[ 7] , cp1*mr, sp1*mr, 0, 1 );
CP(mpCtrlPts[ 8] , cp1*mr, sp1*mr, 0, 1 );
CP(mpCtrlPts[ 9] , cp1*mr, sp1*mr, 0, 1 );
CP(mpCtrlPts[10] , cp1*r, sp1*r, DZ, 1 );
CP(mpCtrlPts[11] , cp1*R, sp1*R, DZ, 1 );
CP(mpCtrlPts[12] , cp1*R, sp1*R, -DZ, 1 );
CP(mpCtrlPts[13] , cp1*r, sp1*r, -DZ, 1 );
CP(mpCtrlPts[14] , cp1*r, sp1*r, DZ, 1 );
t_indCtrlPt i = 15;
G4double srcAngle = PHI1;
G4double deltaAngleo2;
G4double destAngle = M_PI_2 + PHI1;
for(; f > 0; f--)
{
// the first arc CP is already Done
deltaAngleo2 = (destAngle - srcAngle) / 2;
const G4double csa = cos(srcAngle);
const G4double ssa = sin(srcAngle);
const G4double tdao2 = tan(deltaAngleo2);
// to calculate the intermediate CP :
// rotate by srcAngle the (1, tdao2) point
const t_Coord x = csa - ssa*tdao2;
const t_Coord y = ssa + csa*tdao2;
// weight of the CP
const G4Float weight = (cos(deltaAngleo2));
// initialization. postfix ++ because i initialized to 15
CP(mpCtrlPts[i++], x*r, y*r, DZ, 1, weight);
CP(mpCtrlPts[i++], x*R, y*R, DZ, 1, weight);
CP(mpCtrlPts[i++], x*R, y*R, -DZ, 1, weight);
CP(mpCtrlPts[i++], x*r, y*r, -DZ, 1, weight);
CP(mpCtrlPts[i++], x*r, y*r, DZ, 1, weight);
// end CP (which is the first CP of the next arc)
const G4double cda = cos(destAngle);
const G4double sda = sin(destAngle);
CP(mpCtrlPts[i++], cda*r, sda*r, DZ, 1);
CP(mpCtrlPts[i++], cda*R, sda*R, DZ, 1);
CP(mpCtrlPts[i++], cda*R, sda*R, -DZ, 1);
CP(mpCtrlPts[i++], cda*r, sda*r, -DZ, 1);
CP(mpCtrlPts[i++], cda*r, sda*r, DZ, 1);
// prepare next arc
srcAngle = destAngle;
destAngle += M_PI_2;
};
// f == 0, final Arc
// could be handled in the loops
destAngle = PHI2;
deltaAngleo2 = (destAngle - srcAngle) / 2;
const G4double csa = cos(srcAngle);
const G4double ssa = sin(srcAngle);
const G4double tdao2 = tan(deltaAngleo2);
// to calculate the intermediate CP :
// rotate by srcAngle the (1, tdao2) point
const t_Coord x = csa - ssa*tdao2;
const t_Coord y = ssa + csa*tdao2;
// weight of the CP
const G4Float weight = (cos(deltaAngleo2));
// initialization.
CP(mpCtrlPts[i++], x*r, y*r, DZ, 1, weight);
CP(mpCtrlPts[i++], x*R, y*R, DZ, 1, weight);
CP(mpCtrlPts[i++], x*R, y*R, -DZ, 1, weight);
CP(mpCtrlPts[i++], x*r, y*r, -DZ, 1, weight);
CP(mpCtrlPts[i++], x*r, y*r, DZ, 1, weight);
// end CP
const G4double cda = cos(destAngle);
const G4double sda = sin(destAngle);
CP(mpCtrlPts[i++], cda*r, sda*r, DZ, 1);
CP(mpCtrlPts[i++], cda*R, sda*R, DZ, 1);
CP(mpCtrlPts[i++], cda*R, sda*R, -DZ, 1);
CP(mpCtrlPts[i++], cda*r, sda*r, -DZ, 1);
CP(mpCtrlPts[i++], cda*r, sda*r, DZ, 1);
/**/ if (i != (mtotnbrCtrlPts - 10) )
{ G4cerr
<< "\nERROR: G4NURBStubesector::G4NURBStubesector: wrong index,"
<< i << " instead of " << (mtotnbrCtrlPts - 10)
<< "\n\tIt sounds very strange. The tubesector won't be correct. Have a nice debuging!"
<< endl;
};
CP(mpCtrlPts[i++] , cp2*mr, sp2*mr, 0, 1);
CP(mpCtrlPts[i++] , cp2*mr, sp2*mr, 0, 1);
CP(mpCtrlPts[i++] , cp2*mr, sp2*mr, 0, 1);
CP(mpCtrlPts[i++] , cp2*mr, sp2*mr, 0, 1);
CP(mpCtrlPts[i++] , cp2*mr, sp2*mr, 0, 1);
CP(mpCtrlPts[i++] , cp2*mr, sp2*mr, 0, 1);
CP(mpCtrlPts[i++] , cp2*mr, sp2*mr, 0, 1);
CP(mpCtrlPts[i++] , cp2*mr, sp2*mr, 0, 1);
CP(mpCtrlPts[i++] , cp2*mr, sp2*mr, 0, 1);
CP(mpCtrlPts[i++] , cp2*mr, sp2*mr, 0, 1);
// possible to put a DZ DZ -DZ -DZ DZ column to scratch to a line instead of a point
// creating the nurbs identity
mpwhoami = new char [200];
ostrstream tmpstr(mpwhoami, 200);
tmpstr << "Tubs" << " \tPHI1=" << PHI1 << " ; PHI2=" << PHI2 << '\0';
// could be more sophisticated, reallocating
// mpwhoami to the exact length
}
const char* G4NURBStubesector::Whoami() const
{
return mpwhoami;
}
G4NURBStubesector::~G4NURBStubesector()
{
if (mpwhoami) { delete mpwhoami; mpwhoami = NULL; };
}
G4NURBStubesector::t_inddCtrlPt G4NURBStubesector::DecideNbrCtrlPts(G4double PHI1, G4double PHI2)
{
// check angles
G4double deltaPHI = PHI2-PHI1;
while (deltaPHI <= 0) { PHI2 += 2*M_PI; deltaPHI += 2*M_PI; };
G4double k = deltaPHI / (M_PI_2);
// G4cerr << " k " << k << endl;
// G4cerr << " fk " << floor(k) << endl;
// G4cerr << " ifk " << ((int)(floor(k))) << endl;
// G4cerr << " n " << (2*((int)(floor(k))) + 7) << endl;
return ( 2*((int)(floor(k))) + 7 );
}
+23
View File
@@ -0,0 +1,23 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Point3DList.cc,v 2.1 1998/07/13 16:56:18 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison July 1995
#include "G4Point3DList.hh"
#include "G4ios.hh"
ostream& operator << (ostream& os, const G4Point3DList& points)
{
os << "G4Point3DList[" << points.entries() << "]: ";
for (int i = 0; i < points.entries(); i++) os << points(i);
return os;
}
File diff suppressed because it is too large Load Diff
+25
View File
@@ -0,0 +1,25 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Polyline.cc,v 2.0 1998/07/02 17:30:57 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison July 1995
#include "G4Polyline.hh"
G4Polyline::G4Polyline (const G4VVisPrim& prim):
G4VVisPrim (prim)
{}
ostream& operator << (ostream& os, const G4Polyline& line) {
os << "G4Polyline: ";
os << '\n' << (G4VVisPrim) line;
os << '\n' << (G4Point3DList) line;
return os;
}
+45
View File
@@ -0,0 +1,45 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Polymarker.cc,v 2.0 1998/07/02 17:30:59 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison November 1996
#include "G4Polymarker.hh"
// Forward declaration for g++ linker.
#ifdef GNU_GCC
#include <rw/tvvector.h>
#include "G4Point3D.hh"
template class RWTValVector<G4Point3D>;
#endif
G4Polymarker::G4Polymarker ():
fMarkerType (line)
{}
ostream& operator << (ostream& os, const G4Polymarker& marker) {
os << "G4Polymarker: type: ";
switch (marker.fMarkerType) {
case G4Polymarker::line:
os << "line"; break;
case G4Polymarker::dots:
os << "dots"; break;
case G4Polymarker::circles:
os << "circles"; break;
case G4Polymarker::squares:
os << "squares"; break;
default:
os << "unrecognised"; break;
}
os << "\n ";
os << (G4VMarker) marker;
os << (G4Point3DList) marker;
return os;
}
+34
View File
@@ -0,0 +1,34 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Text.cc,v 2.0 1998/07/02 17:30:41 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 17/11/96.
#include "G4Text.hh"
G4Text::G4Text (const G4String& text):
fText (text),
fLayout (left),
fXOffset(0.) , fYOffset(0.)
{}
G4Text::G4Text (const G4String& text, const G4Point3D& pos):
G4VMarker (pos),
fText (text),
fLayout (left),
fXOffset(0.) , fYOffset(0.)
{}
G4Text::G4Text (const G4VMarker& marker):
G4VMarker (marker),
fText ("") ,
fLayout (left) ,
fXOffset(0.) , fYOffset(0.)
{}
+48
View File
@@ -0,0 +1,48 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VMarker.cc,v 2.0 1998/07/02 17:31:01 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
#include "G4VMarker.hh"
#include "G4VisAttributes.hh"
ostream& operator << (ostream& os, const G4VMarker& marker) {
os << "G4VMarker: position: " << marker.fPosition
<< ", world size: " << marker.fWorldSize
<< ", screen size: " << marker.fScreenSize << '\n'
<< " fill style: ";
switch (marker.fFillStyle) {
case G4VMarker::noFill:
os << "no fill";
break;
case G4VMarker::hashed:
os << "hashed";
break;
case G4VMarker::filled:
os << "filled";
break;
default:
os << "unrecognised"; break;
}
os << "\n " << (G4VVisPrim) marker;
return os;
}
G4bool operator != (const G4VMarker& m1, const G4VMarker& m2) {
if (
(m1.fWorldSize != m2.fWorldSize) ||
(m1.fScreenSize != m2.fScreenSize) ||
(m1.fFillStyle != m2.fFillStyle) ||
!(m1.fPosition == m2.fPosition)
)
return true;
return false;
}
+17
View File
@@ -0,0 +1,17 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VVisManager.cc,v 2.0 1998/07/02 17:31:02 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// Abstract interface for GEANT4 Visualization Manager.
// John Allison 19/Oct/1996.
#include "G4VVisManager.hh"
G4VVisManager* G4VVisManager::fpConcreteInstance = 0;
+20
View File
@@ -0,0 +1,20 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VVisPrim.cc,v 2.1 1998/07/13 16:56:21 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison August 1995
#include "G4VVisPrim.hh"
#include "G4VisAttributes.hh"
#include "G4ios.hh"
ostream& operator << (ostream& os, const G4VVisPrim& prim) {
return os << (G4Visible) prim;
}
+104
View File
@@ -0,0 +1,104 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VisAttributes.cc,v 2.0 1998/07/02 17:31:05 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 23rd October 1996
#include "G4VisAttributes.hh"
G4VisAttributes::G4VisAttributes ():
fVisible (true),
fColour (G4Colour ()),
fLineStyle (unbroken),
fLineWidth (1.),
fForceDrawingStyle (false)
{}
G4VisAttributes::G4VisAttributes (G4bool visibility):
fVisible (visibility),
fColour (G4Colour ()),
fLineStyle (unbroken),
fLineWidth (1.),
fForceDrawingStyle (false)
{}
G4VisAttributes::G4VisAttributes (const G4Colour& colour):
fVisible (true),
fColour (colour),
fLineStyle (unbroken),
fLineWidth (1.),
fForceDrawingStyle (false)
{}
G4VisAttributes::G4VisAttributes (G4bool visibility,
const G4Colour& colour):
fVisible (visibility),
fColour (colour),
fLineStyle (unbroken),
fLineWidth (1.),
fForceDrawingStyle (false)
{}
const G4VisAttributes G4VisAttributes::Invisible = G4VisAttributes (false);
ostream& operator << (ostream& os, const G4VisAttributes& a) {
os << "G4VisAttributes: ";
if (&a){
if (!a.fVisible) os << " in";
os << "visible, colour: " << a.fColour;
os << "\n linestyle: ";
switch (a.fLineStyle) {
case G4VisAttributes::unbroken:
os << "solid"; break;
case G4VisAttributes::dashed:
os << "dashed"; break;
case G4VisAttributes::dotted: os << "dotted"; break;
default: os << "unrecognised"; break;
}
os << ", line width: " << a.fLineWidth;
os << "\n drawing style ";
if (a.fForceDrawingStyle) {
os << "forced to: ";
switch (a.fForcedStyle) {
case G4VisAttributes::wireframe:
os << "wireframe"; break;
case G4VisAttributes::solid:
os << "solid"; break;
default: os << "unrecognised"; break;
}
}
else {
os << "unforced";
}
}
else os << " The pointer is zero ";
return os;
}
G4bool operator != (const G4VisAttributes& a1,
const G4VisAttributes& a2) {
if (
(a1.fVisible != a2.fVisible) ||
(a1.fColour != a2.fColour) ||
(a1.fLineStyle != a2.fLineStyle) ||
(a1.fLineWidth != a2.fLineWidth) ||
(a1.fForceDrawingStyle != a2.fForceDrawingStyle)
)
return true;
if (a1.fForceDrawingStyle) {
if (a1.fForcedStyle != a2.fForcedStyle) return true;
}
return false;
}
+68
View File
@@ -0,0 +1,68 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VisExtent.cc,v 2.2 1998/08/22 16:20:43 allison Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// A.Walkden 28/11/95
// G4VisExtent.cc - to return parameters useful to the drawing window
// employed by Visualization code.
#include "G4VisExtent.hh"
#include "G4ios.hh"
G4VisExtent::G4VisExtent (G4double xmin, G4double xmax,
G4double ymin, G4double ymax,
G4double zmin, G4double zmax)
:fXmin(xmin), fXmax(xmax), fYmin(ymin), fYmax(ymax), fZmin(zmin), fZmax(zmax)
{}
G4VisExtent::G4VisExtent (const G4Point3D& centre, G4double radius) {
// Use inscribed radius to define G3VisExtent so that
// GetExtentRadius gets radius back again. The one is the "inverse"
// of the other, so to speak.
G4double inscribedRadius = radius / sqrt (3.);
fXmin = centre.x () - inscribedRadius;
fXmax = centre.x () + inscribedRadius;
fYmin = centre.y () - inscribedRadius;
fYmax = centre.y () + inscribedRadius;
fZmin = centre.z () - inscribedRadius;
fZmax = centre.z () + inscribedRadius;
}
G4VisExtent::~G4VisExtent () {}
G4Point3D G4VisExtent::GetExtentCentre () const {
return G4Point3D (((fXmin + fXmax) / 2.),
((fYmin + fYmax) / 2.),
((fZmin + fZmax) / 2.));
}
G4double G4VisExtent::GetExtentRadius () const {
return sqrt (((fXmax - fXmin) * (fXmax - fXmin)) +
((fYmax - fYmin) * (fYmax - fYmin)) +
((fZmax - fZmin) * (fZmax - fZmin))) / 2;
}
ostream& operator << (ostream& os, const G4VisExtent& e) {
os << "G4VisExtent (bounding box):";
os << "\n X limits: " << e.fXmin << ' ' << e.fXmax;
os << "\n Y limits: " << e.fYmin << ' ' << e.fYmax;
os << "\n Z limits: " << e.fZmin << ' ' << e.fZmax;
return os;
}
G4bool operator != (const G4VisExtent& e1, const G4VisExtent& e2) {
return ((e1.fXmin != e2.fXmin) ||
(e1.fXmax != e2.fXmax) ||
(e1.fYmin != e2.fYmin) ||
(e1.fYmax != e2.fYmax) ||
(e1.fZmin != e2.fZmin) ||
(e1.fZmax != e2.fZmax));
}
+22
View File
@@ -0,0 +1,22 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Visible.cc,v 2.1 1998/07/13 16:56:24 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// John Allison 30th October 1996
// Base class for all things visible, i.e., which have Vis Attributes.
#include "G4Visible.hh"
#include "G4VisAttributes.hh"
#include "G4ios.hh"
ostream& operator << (ostream& os, const G4Visible& v) {
if (v.fpVisAttributes) return os << *(v.fpVisAttributes);
else return os << "No Visualization Attributes";
}