| 1 | //
 | 
|---|
| 2 | // shape.h
 | 
|---|
| 3 | //
 | 
|---|
| 4 | // Copyright (C) 1996 Limit Point Systems, Inc.
 | 
|---|
| 5 | //
 | 
|---|
| 6 | // Author: Curtis Janssen <cljanss@limitpt.com>
 | 
|---|
| 7 | // Maintainer: LPS
 | 
|---|
| 8 | //
 | 
|---|
| 9 | // This file is part of the SC Toolkit.
 | 
|---|
| 10 | //
 | 
|---|
| 11 | // The SC Toolkit is free software; you can redistribute it and/or modify
 | 
|---|
| 12 | // it under the terms of the GNU Library General Public License as published by
 | 
|---|
| 13 | // the Free Software Foundation; either version 2, or (at your option)
 | 
|---|
| 14 | // any later version.
 | 
|---|
| 15 | //
 | 
|---|
| 16 | // The SC Toolkit is distributed in the hope that it will be useful,
 | 
|---|
| 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
| 19 | // GNU Library General Public License for more details.
 | 
|---|
| 20 | //
 | 
|---|
| 21 | // You should have received a copy of the GNU Library General Public License
 | 
|---|
| 22 | // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
 | 
|---|
| 23 | // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
|---|
| 24 | //
 | 
|---|
| 25 | // The U.S. Government is granted a limited license as per AL 91-7.
 | 
|---|
| 26 | //
 | 
|---|
| 27 | 
 | 
|---|
| 28 | #ifndef _math_isosurf_shape_h
 | 
|---|
| 29 | #define _math_isosurf_shape_h
 | 
|---|
| 30 | 
 | 
|---|
| 31 | #ifdef __GNUC__
 | 
|---|
| 32 | #pragma interface
 | 
|---|
| 33 | #endif
 | 
|---|
| 34 | 
 | 
|---|
| 35 | #include <set>
 | 
|---|
| 36 | 
 | 
|---|
| 37 | #include <math/isosurf/volume.h>
 | 
|---|
| 38 | #include <math/scmat/matrix.h>
 | 
|---|
| 39 | #include <math/scmat/vector3.h>
 | 
|---|
| 40 | 
 | 
|---|
| 41 | namespace sc {
 | 
|---|
| 42 | 
 | 
|---|
| 43 | /** A Shape is a Volume represents an 3D solid.  The value of the Shape at
 | 
|---|
| 44 | each point in space is the distance to the surface.  The distance is
 | 
|---|
| 45 | negative if the point is inside the solid.  For Shape specializations that
 | 
|---|
| 46 | cannot compute the distance to the surface, the value will be 1.0 outside
 | 
|---|
| 47 | and -1.0 inside the solid. */
 | 
|---|
| 48 | class Shape: public Volume {
 | 
|---|
| 49 |   public:
 | 
|---|
| 50 |     Shape();
 | 
|---|
| 51 |     Shape(const Ref<KeyVal>&keyval);
 | 
|---|
| 52 |     virtual double distance_to_surface(const SCVector3&r,
 | 
|---|
| 53 |                                        SCVector3*grad=0) const = 0;
 | 
|---|
| 54 |     virtual int is_outside(const SCVector3&r) const;
 | 
|---|
| 55 |     virtual ~Shape();
 | 
|---|
| 56 |     void compute();
 | 
|---|
| 57 |     void interpolate(const SCVector3& p1,
 | 
|---|
| 58 |                      const SCVector3& p2,
 | 
|---|
| 59 |                      double val,
 | 
|---|
| 60 |                      SCVector3& result);
 | 
|---|
| 61 | 
 | 
|---|
| 62 |     int value_implemented() const;
 | 
|---|
| 63 | };
 | 
|---|
| 64 | 
 | 
|---|
| 65 | 
 | 
|---|
| 66 | 
 | 
|---|
| 67 | class SphereShape: public Shape {
 | 
|---|
| 68 |   private:
 | 
|---|
| 69 |     SCVector3 _origin;
 | 
|---|
| 70 |     double _radius;
 | 
|---|
| 71 |   public:
 | 
|---|
| 72 |     SphereShape(const SCVector3&,double);
 | 
|---|
| 73 |     SphereShape(const Ref<KeyVal>&);
 | 
|---|
| 74 |     SphereShape(const SphereShape&);
 | 
|---|
| 75 |     ~SphereShape();
 | 
|---|
| 76 |     void boundingbox(double minvalue, double maxvalue,
 | 
|---|
| 77 |                      SCVector3& p1, SCVector3&p2);
 | 
|---|
| 78 |     double radius() const { return _radius; }
 | 
|---|
| 79 |     const SCVector3& origin() const { return _origin; }
 | 
|---|
| 80 |     double distance_to_surface(const SCVector3&r,SCVector3*grad=0) const;
 | 
|---|
| 81 |     void print(std::ostream&o=ExEnv::out0()) const;
 | 
|---|
| 82 | 
 | 
|---|
| 83 |     // these are used to update the parameters describing the sphere
 | 
|---|
| 84 |     double radius(double r);
 | 
|---|
| 85 |     const SCVector3& origin(const SCVector3& o);
 | 
|---|
| 86 | 
 | 
|---|
| 87 |     int gradient_implemented() const;
 | 
|---|
| 88 | };
 | 
|---|
| 89 | 
 | 
|---|
| 90 | inline double
 | 
|---|
| 91 | SphereShape::radius(double r)
 | 
|---|
| 92 | {
 | 
|---|
| 93 |   obsolete();
 | 
|---|
| 94 |   return _radius = r;
 | 
|---|
| 95 | }
 | 
|---|
| 96 | 
 | 
|---|
| 97 | inline const SCVector3&
 | 
|---|
| 98 | SphereShape::origin(const SCVector3& o)
 | 
|---|
| 99 | {
 | 
|---|
| 100 |   obsolete();
 | 
|---|
| 101 |   _origin = o;
 | 
|---|
| 102 |   return _origin;
 | 
|---|
| 103 | }
 | 
|---|
| 104 | 
 | 
|---|
| 105 | class UncappedTorusHoleShape: public Shape
 | 
|---|
| 106 | {
 | 
|---|
| 107 |   private:
 | 
|---|
| 108 |     SphereShape _s1;
 | 
|---|
| 109 |     SphereShape _s2;
 | 
|---|
| 110 |     double _r;
 | 
|---|
| 111 |   protected:
 | 
|---|
| 112 |     void in_plane_sphere(const SCVector3& point,
 | 
|---|
| 113 |                          SCVector3& origin) const;
 | 
|---|
| 114 |     UncappedTorusHoleShape(double r,const SphereShape&,const SphereShape&);
 | 
|---|
| 115 |   public:
 | 
|---|
| 116 |     static UncappedTorusHoleShape*
 | 
|---|
| 117 |     newUncappedTorusHoleShape(double r,
 | 
|---|
| 118 |                               const SphereShape&,
 | 
|---|
| 119 |                               const SphereShape&);
 | 
|---|
| 120 |     inline ~UncappedTorusHoleShape() {};
 | 
|---|
| 121 |     inline const SphereShape& sphere(int i) const { return (i?_s2:_s1); };
 | 
|---|
| 122 |     inline const SCVector3 A() const { SCVector3 v(_s1.origin()); return v; }
 | 
|---|
| 123 |     inline const SCVector3 B() const { SCVector3 v(_s2.origin()); return v; }
 | 
|---|
| 124 |     inline double radius() const { return _r; };
 | 
|---|
| 125 |     void print(std::ostream&o=ExEnv::out0()) const;
 | 
|---|
| 126 |     void boundingbox(double valuemin, double valuemax,
 | 
|---|
| 127 |                      SCVector3& p1, SCVector3&p2);
 | 
|---|
| 128 | 
 | 
|---|
| 129 |     int gradient_implemented() const;
 | 
|---|
| 130 | };
 | 
|---|
| 131 | 
 | 
|---|
| 132 | class NonreentrantUncappedTorusHoleShape: public UncappedTorusHoleShape
 | 
|---|
| 133 | {
 | 
|---|
| 134 |   private:
 | 
|---|
| 135 |     double rAP;
 | 
|---|
| 136 |     double rBP;
 | 
|---|
| 137 |     SCVector3 BA;
 | 
|---|
| 138 |   public:
 | 
|---|
| 139 |     NonreentrantUncappedTorusHoleShape(double r,
 | 
|---|
| 140 |                                        const SphereShape&,
 | 
|---|
| 141 |                                        const SphereShape&);
 | 
|---|
| 142 |     ~NonreentrantUncappedTorusHoleShape();
 | 
|---|
| 143 |     double distance_to_surface(const SCVector3&r,SCVector3*grad=0) const;
 | 
|---|
| 144 | 
 | 
|---|
| 145 |     int gradient_implemented() const;
 | 
|---|
| 146 | };
 | 
|---|
| 147 | 
 | 
|---|
| 148 | class ReentrantUncappedTorusHoleShape: public UncappedTorusHoleShape
 | 
|---|
| 149 | {
 | 
|---|
| 150 |   private:
 | 
|---|
| 151 |     double rAP;
 | 
|---|
| 152 |     double rBP;
 | 
|---|
| 153 |     SCVector3 BA;
 | 
|---|
| 154 |     SCVector3 I[2]; // the intersect points
 | 
|---|
| 155 |   public:
 | 
|---|
| 156 |     ReentrantUncappedTorusHoleShape(double r,
 | 
|---|
| 157 |                                     const SphereShape&,
 | 
|---|
| 158 |                                     const SphereShape&);
 | 
|---|
| 159 |     ~ReentrantUncappedTorusHoleShape();
 | 
|---|
| 160 |     int is_outside(const SCVector3&r) const;
 | 
|---|
| 161 |     double distance_to_surface(const SCVector3&r,SCVector3*grad=0) const;
 | 
|---|
| 162 | 
 | 
|---|
| 163 |     int gradient_implemented() const;
 | 
|---|
| 164 | };
 | 
|---|
| 165 | 
 | 
|---|
| 166 | class Uncapped5SphereExclusionShape: public Shape
 | 
|---|
| 167 | {
 | 
|---|
| 168 |   private:
 | 
|---|
| 169 |     int _solution_exists;
 | 
|---|
| 170 |     int _reentrant;
 | 
|---|
| 171 |     int _folded;
 | 
|---|
| 172 |     SphereShape _s1;
 | 
|---|
| 173 |     SphereShape _s2;
 | 
|---|
| 174 |     SphereShape _s3;
 | 
|---|
| 175 |     SCVector3 D[2];
 | 
|---|
| 176 |     double BDxCDdotAD[2];
 | 
|---|
| 177 |     SCVector3 BDxCD[2];
 | 
|---|
| 178 |     double CDxADdotBD[2];
 | 
|---|
| 179 |     SCVector3 CDxAD[2];
 | 
|---|
| 180 |     double ADxBDdotCD[2];
 | 
|---|
| 181 |     SCVector3 ADxBD[2];
 | 
|---|
| 182 |     double _r;
 | 
|---|
| 183 | 
 | 
|---|
| 184 |     // these are needed for folded shapes
 | 
|---|
| 185 |     // F1 and F2 are the two points of A, B, and C that are closed to M
 | 
|---|
| 186 |     SCVector3 F1;
 | 
|---|
| 187 |     SCVector3 F2;
 | 
|---|
| 188 |     
 | 
|---|
| 189 |     // these are needed for reentrant surfaces to compute distances
 | 
|---|
| 190 |     SCVector3 M;   // projection of D onto ABC plane
 | 
|---|
| 191 |     SCVector3 MD[2];  // M - D 
 | 
|---|
| 192 |     double theta_intersect; // angle M - D - intersect_point
 | 
|---|
| 193 |     double r_intersect; // the radius of the intersect circle
 | 
|---|
| 194 |     int _intersects_AB;
 | 
|---|
| 195 |     SCVector3 IABD[2][2];
 | 
|---|
| 196 |     int _intersects_BC;
 | 
|---|
| 197 |     SCVector3 IBCD[2][2];
 | 
|---|
| 198 |     int _intersects_CA;
 | 
|---|
| 199 |     SCVector3 ICAD[2][2];
 | 
|---|
| 200 |     
 | 
|---|
| 201 |   protected:
 | 
|---|
| 202 |     Uncapped5SphereExclusionShape(double r,
 | 
|---|
| 203 |                                   const SphereShape&,
 | 
|---|
| 204 |                                   const SphereShape&,
 | 
|---|
| 205 |                                   const SphereShape&);
 | 
|---|
| 206 |   public:
 | 
|---|
| 207 |     static Uncapped5SphereExclusionShape*
 | 
|---|
| 208 |     newUncapped5SphereExclusionShape(double r,
 | 
|---|
| 209 |                                      const SphereShape&,
 | 
|---|
| 210 |                                      const SphereShape&,
 | 
|---|
| 211 |                                      const SphereShape&);
 | 
|---|
| 212 |     inline ~Uncapped5SphereExclusionShape() {};
 | 
|---|
| 213 |     inline const SCVector3 A() const { SCVector3 v(_s1.origin()); return v; }
 | 
|---|
| 214 |     inline const SCVector3 B() const { SCVector3 v(_s2.origin()); return v; }
 | 
|---|
| 215 |     inline const SCVector3 C() const { SCVector3 v(_s3.origin()); return v; }
 | 
|---|
| 216 |     inline double rA() const { return _s1.radius(); };
 | 
|---|
| 217 |     inline double rB() const { return _s2.radius(); };
 | 
|---|
| 218 |     inline double rC() const { return _s3.radius(); };
 | 
|---|
| 219 |     inline double r() const { return _r; };
 | 
|---|
| 220 |     inline int solution_exists() const { return _solution_exists; };
 | 
|---|
| 221 |     double distance_to_surface(const SCVector3&r,SCVector3*grad=0) const;
 | 
|---|
| 222 |     int is_outside(const SCVector3&) const;
 | 
|---|
| 223 |     void boundingbox(double valuemin, double valuemax,
 | 
|---|
| 224 |                      SCVector3& p1, SCVector3&p2);
 | 
|---|
| 225 | 
 | 
|---|
| 226 |     int gradient_implemented() const;
 | 
|---|
| 227 | };
 | 
|---|
| 228 | 
 | 
|---|
| 229 | /** A UnionShape is volume enclosed by a set of Shape's. */
 | 
|---|
| 230 | class UnionShape: public Shape {
 | 
|---|
| 231 |   protected:
 | 
|---|
| 232 |     std::set<Ref<Shape> > _shapes;
 | 
|---|
| 233 |   public:
 | 
|---|
| 234 |     void add_shape(Ref<Shape>);
 | 
|---|
| 235 |     UnionShape();
 | 
|---|
| 236 |     ~UnionShape();
 | 
|---|
| 237 |     double distance_to_surface(const SCVector3&r,SCVector3*grad=0) const;
 | 
|---|
| 238 |     int is_outside(const SCVector3&r) const;
 | 
|---|
| 239 |     void boundingbox(double valuemin, double valuemax,
 | 
|---|
| 240 |                      SCVector3& p1, SCVector3& p2);
 | 
|---|
| 241 | 
 | 
|---|
| 242 |     int gradient_implemented() const;
 | 
|---|
| 243 | };
 | 
|---|
| 244 | 
 | 
|---|
| 245 | }
 | 
|---|
| 246 | 
 | 
|---|
| 247 | #endif
 | 
|---|
| 248 | 
 | 
|---|
| 249 | // Local Variables:
 | 
|---|
| 250 | // mode: c++
 | 
|---|
| 251 | // c-file-style: "CLJ"
 | 
|---|
| 252 | // End:
 | 
|---|