00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef ISOEX_CSG_HH
00034 #define ISOEX_CSG_HH
00035
00036
00037
00038
00039 #include <IsoEx/Implicits/Implicit.hh>
00040
00041
00042
00043 namespace IsoEx {
00044 namespace CSG {
00045
00046
00047
00048
00054 class Union : public Implicit
00055 {
00056 public:
00057
00059 Union(const Implicit& _implicit1, const Implicit& _implicit2)
00060 : implicit1_(_implicit1), implicit2_(_implicit2)
00061 {}
00062
00063
00065
00066
00067 bool is_inside(const OpenMesh::Vec3f& _p) const {
00068 return implicit1_.is_inside(_p) || implicit2_.is_inside(_p);
00069 }
00070
00071 float scalar_distance(const OpenMesh::Vec3f& _p) const {
00072 return std::min(implicit1_.scalar_distance(_p),
00073 implicit2_.scalar_distance(_p));
00074 }
00075
00076 bool directed_distance(const OpenMesh::Vec3f& _p0,
00077 const OpenMesh::Vec3f& _p1,
00078 OpenMesh::Vec3f& _point,
00079 OpenMesh::Vec3f& _normal,
00080 float& _distance) const
00081 {
00082 bool ok1, ok2;
00083 OpenMesh::Vec3f p1, n1, p2, n2;
00084 float d1, d2;
00085
00086 ok1 = implicit1_.directed_distance(_p0, _p1, p1, n1, d1);
00087 ok2 = implicit2_.directed_distance(_p0, _p1, p2, n2, d2);
00088
00089 if (ok1 && ok2) { if (d1 < d2) ok2 = false; else ok1 = false; }
00090
00091 if (ok1) { _point = p1; _normal = n1; _distance = d1; return true; }
00092 else if (ok2) { _point = p2; _normal = n2; _distance = d2; return true; }
00093
00094 return false;
00095 }
00096
00098
00099 private:
00100
00101 const Implicit& implicit1_;
00102 const Implicit& implicit2_;
00103 };
00104
00105
00106
00107
00108
00109
00110
00116 class Intersection : public Implicit
00117 {
00118 public:
00119
00121 Intersection(const Implicit& _implicit1, const Implicit& _implicit2)
00122 : implicit1_(_implicit1), implicit2_(_implicit2)
00123 {}
00124
00125
00127
00128
00129 bool is_inside(const OpenMesh::Vec3f& _p) const {
00130 return (implicit1_.is_inside(_p) && implicit2_.is_inside(_p));
00131 }
00132
00133 float scalar_distance(const OpenMesh::Vec3f& _p) const {
00134 return std::max(implicit1_.scalar_distance(_p),
00135 implicit2_.scalar_distance(_p));
00136 }
00137
00138 bool directed_distance(const OpenMesh::Vec3f& _p0,
00139 const OpenMesh::Vec3f& _p1,
00140 OpenMesh::Vec3f& _point,
00141 OpenMesh::Vec3f& _normal,
00142 float& _distance) const
00143 {
00144 bool ok1, ok2;
00145 OpenMesh::Vec3f p1, n1, p2, n2;
00146 float d1, d2;
00147
00148 ok1 = implicit1_.directed_distance(_p0, _p1, p1, n1, d1);
00149 ok2 = implicit2_.directed_distance(_p0, _p1, p2, n2, d2);
00150
00151 if (ok1 && ok2) { if (d1 > d2) ok2 = false; else ok1 = false; }
00152
00153 if (ok1) { _point = p1; _normal = n1; _distance = d1; return true; }
00154 else if (ok2) { _point = p2; _normal = n2; _distance = d2; return true; }
00155
00156 return false;
00157 }
00158
00160
00161
00162 private:
00163
00164 const Implicit& implicit1_;
00165 const Implicit& implicit2_;
00166 };
00167
00168
00169
00170
00171
00172
00173
00179 class Difference : public Implicit
00180 {
00181 public:
00182
00186 Difference(const Implicit& _implicit1, const Implicit& _implicit2)
00187 : implicit1_(_implicit1), implicit2_(_implicit2)
00188 {}
00189
00190
00192
00193
00194 bool is_inside(const OpenMesh::Vec3f& _p) const {
00195 return implicit1_.is_inside(_p) && !implicit2_.is_inside(_p);
00196 }
00197
00198 float scalar_distance(const OpenMesh::Vec3f& _p) const {
00199 return std::max(implicit1_.scalar_distance(_p),
00200 -implicit2_.scalar_distance(_p));
00201 }
00202
00203 bool directed_distance(const OpenMesh::Vec3f& _p0,
00204 const OpenMesh::Vec3f& _p1,
00205 OpenMesh::Vec3f& _point,
00206 OpenMesh::Vec3f& _normal,
00207 float& _distance) const
00208 {
00209 bool ok1, ok2;
00210 OpenMesh::Vec3f p1, n1, p2, n2;
00211 float d1, d2;
00212
00213 ok1 = implicit1_.directed_distance(_p0, _p1, p1, n1, d1);
00214 ok2 = implicit2_.directed_distance(_p0, _p1, p2, n2, d2);
00215 d2 = -d2;
00216
00217 if (ok1 && ok2) { if (d1 > d2) ok2 = false; else ok1 = false; }
00218
00219 if (ok1) { _point = p1; _normal = n1; _distance = d1; return true; }
00220 else if (ok2) { _point = p2; _normal = n2; _distance = d2; return true; }
00221
00222 return false;
00223 }
00224
00226
00227 private:
00228
00229 const Implicit& implicit1_;
00230 const Implicit& implicit2_;
00231 };
00232
00233
00234
00235
00236 }
00237 }
00238
00239 #endif // ISOEX_CSG_HH defined
00240
00241