From cf0883ea4cc4081d0fbdb923d2afcac600b972d1 Mon Sep 17 00:00:00 2001
From: Laurent Van Migroet <l.vanmiegroet@ulg.ac.be>
Date: Thu, 4 Feb 2010 22:19:23 +0000
Subject: [PATCH] added copy constuctor and clone method

---
 contrib/DiscreteIntegration/DILevelset.cpp | 55 +++++++++++++++++++---
 contrib/DiscreteIntegration/DILevelset.h   | 41 ++++++++++++++--
 2 files changed, 86 insertions(+), 10 deletions(-)

diff --git a/contrib/DiscreteIntegration/DILevelset.cpp b/contrib/DiscreteIntegration/DILevelset.cpp
index 03a4c5bd0d..7bfa00bd24 100644
--- a/contrib/DiscreteIntegration/DILevelset.cpp
+++ b/contrib/DiscreteIntegration/DILevelset.cpp
@@ -80,6 +80,11 @@ void gLevelset::getRPN(std::vector<const gLevelset *> &gLsRPN) const {
   }
 }
 
+gLevelset::gLevelset(const gLevelset &lv)
+{
+	tag_=lv.tag_;
+}
+
 gLevelsetPlane::gLevelsetPlane(const double * pt, const double *norm, int &tag) : gLevelsetPrimitive(tag) {
   a = norm[0];
   b = norm[1];
@@ -92,7 +97,12 @@ gLevelsetPlane::gLevelsetPlane(const double * pt1, const double *pt2, const doub
   c = det3(pt1[0], pt1[1], 1., pt2[0], pt2[1], 1., pt3[0], pt3[1], 1.);
   d = -det3(pt1[0], pt1[1], pt1[2], pt2[0], pt2[1], pt2[2], pt3[0], pt3[1], pt3[2]);
 }
-
+gLevelsetPlane::gLevelsetPlane(const gLevelsetPlane &lv) : gLevelsetPrimitive(lv) {
+  a = lv.a;
+  b = lv.b;
+  c = lv.c;
+  d = lv.d;
+}
 /*
   assume a quadric 
   x^T A x + b^T x + c = 0
@@ -104,6 +114,14 @@ gLevelsetPlane::gLevelsetPlane(const double * pt1, const double *pt2, const doub
   x^T A x + [b^T - 2 A t] x + [c - b^T t + t^T A t ] = 0
 */
 
+gLevelsetQuadric::gLevelsetQuadric(const gLevelsetQuadric &lv):gLevelsetPrimitive(lv)
+{
+	for(int i = 0; i < 3; i++){
+		B[i] = lv.B[i];
+		for(int j = 0; j < 3; j++) A[i][j] = lv.A[i][j];
+	}
+	C=lv.C;
+}
 void gLevelsetQuadric::Ax(const double x[3], double res[3], double fact){
   for(int i = 0; i < 3; i++){
     res[i] = 0.;
@@ -226,6 +244,7 @@ gLevelsetGenCylinder::gLevelsetGenCylinder(const double *pt, const double *dir,
   rotate(rot);
   translate(pt);
 }
+gLevelsetGenCylinder::gLevelsetGenCylinder (const gLevelsetGenCylinder& lv):gLevelsetQuadric(lv){}
 
 gLevelsetEllipsoid::gLevelsetEllipsoid(const double *pt, const double *dir, const double &a, 
                                        const double &b, const double &c, int &tag) : gLevelsetQuadric(tag) {
@@ -238,6 +257,7 @@ gLevelsetEllipsoid::gLevelsetEllipsoid(const double *pt, const double *dir, cons
   rotate(rot);
   translate(pt);
 }
+gLevelsetEllipsoid::gLevelsetEllipsoid (const gLevelsetEllipsoid& lv):gLevelsetQuadric(lv){}
 
 gLevelsetCone::gLevelsetCone(const double *pt, const double *dir, const double &angle, int &tag) : gLevelsetQuadric(tag) {
   A[0][0] = 1.;
@@ -249,6 +269,8 @@ gLevelsetCone::gLevelsetCone(const double *pt, const double *dir, const double &
   translate(pt);
 }
 
+gLevelsetCone::gLevelsetCone (const gLevelsetCone& lv):gLevelsetQuadric(lv)
+{}
 gLevelsetGeneralQuadric::gLevelsetGeneralQuadric(const double *pt, const double *dir, const double &x2, const double &y2, const double &z2,
                                                  const double &z, const double &c, int &tag) : gLevelsetQuadric(tag) {
   A[0][0] = x2;
@@ -262,8 +284,24 @@ gLevelsetGeneralQuadric::gLevelsetGeneralQuadric(const double *pt, const double
   translate(pt);
 }
 
+gLevelsetGeneralQuadric::gLevelsetGeneralQuadric (const gLevelsetGeneralQuadric& lv):gLevelsetQuadric(lv)
+{}
+
+gLevelsetTools::gLevelsetTools(const gLevelsetTools &lv):gLevelset(lv)
+{
+	std::vector<const gLevelset *> &_children=lv.getChildren();
+	unsigned siz=_children.size();
+	children.resize(siz);
+	for(unsigned i=0;i<siz;++i)	
+		children[i]=_children[i]->clone();
+}
+gLevelsetImproved::gLevelsetImproved(const gLevelsetImproved &lv):gLevelset(lv)
+{
+	Ls=lv.Ls->clone();
+}
+
 gLevelsetBox::gLevelsetBox(const double *pt, const double *dir1, const double *dir2, const double *dir3,
-                           const double &a, const double &b, const double &c, int &tag) {
+						   const double &a, const double &b, const double &c, int &tag):gLevelsetImproved() {
   double dir1m[3] = {-dir1[0], -dir1[1], -dir1[2]};
   double dir2m[3] = {-dir2[0], -dir2[1], -dir2[2]};
   double dir3m[3] = {-dir3[0], -dir3[1], -dir3[2]};
@@ -283,7 +321,7 @@ gLevelsetBox::gLevelsetBox(const double *pt, const double *dir1, const double *d
 }
 
 gLevelsetBox::gLevelsetBox(const double *pt1, const double *pt2, const double *pt3, const double *pt4,
-                           const double *pt5, const double *pt6, const double *pt7, const double *pt8, int &tag) {
+                           const double *pt5, const double *pt6, const double *pt7, const double *pt8, int &tag):gLevelsetImproved() {
   if(!isPlanar(pt1, pt2, pt3, pt4) || !isPlanar(pt5, pt6, pt7, pt8) || !isPlanar(pt1, pt2, pt5, pt6) ||
      !isPlanar(pt3, pt4, pt7, pt8) || !isPlanar(pt1, pt4, pt5, pt8) || !isPlanar(pt2, pt3, pt6, pt7))
     printf("WARNING : faces of the box are not planar! %d, %d, %d, %d, %d, %d\n",
@@ -299,7 +337,9 @@ gLevelsetBox::gLevelsetBox(const double *pt1, const double *pt2, const double *p
   Ls = new gLevelsetIntersection(p);
 }
 
-gLevelsetCylinder::gLevelsetCylinder(const double *pt, const double *dir, const double &R, const double &H, int &tag) {
+gLevelsetBox::gLevelsetBox(const gLevelsetBox &lv):gLevelsetImproved(lv){}
+
+gLevelsetCylinder::gLevelsetCylinder(const double *pt, const double *dir, const double &R, const double &H, int &tag):gLevelsetImproved() {
   double dir2[3] = {-dir[0], -dir[1], -dir[2]};
   double n[3]; norm(dir, n);
   double pt2[3] = {pt[0] + H * n[0], pt[1] + H * n[1], pt[2] + H * n[2]};
@@ -310,7 +350,7 @@ gLevelsetCylinder::gLevelsetCylinder(const double *pt, const double *dir, const
   Ls = new gLevelsetIntersection(p);
 }
 
-gLevelsetCylinder::gLevelsetCylinder(const double * pt, const double *dir, const double &R, const double &r, const double &H, int &tag) {
+gLevelsetCylinder::gLevelsetCylinder(const double * pt, const double *dir, const double &R, const double &r, const double &H, int &tag):gLevelsetImproved() {
   double dir2[3] = {-dir[0], -dir[1], -dir[2]};
   double n[3]; norm(dir, n);
   double pt2[3] = {pt[0] + H * n[0], pt[1] + H * n[1], pt[2] + H * n[2]};
@@ -323,11 +363,12 @@ gLevelsetCylinder::gLevelsetCylinder(const double * pt, const double *dir, const
   p2.push_back(new gLevelsetGenCylinder(pt, dir, r, tag));
   Ls = new gLevelsetCut(p2);
 }
+gLevelsetCylinder::gLevelsetCylinder(const gLevelsetCylinder &lv):gLevelsetImproved(lv){}
 
 gLevelsetConrod::gLevelsetConrod(const double *pt, const double *dir1, const double *dir2,
                                  const double &H1, const double &H2, const double &H3,
                                  const double &R1, const double &r1, const double &R2, const double &r2,
-                                 const double &L1, const double &L2, const double &E, int &tag) {
+								 const double &L1, const double &L2, const double &E, int &tag):gLevelsetImproved() {
   double n1[3]; norm(dir1, n1);
   double n2[3]; norm(dir2, n2);
   double pt1[3] = {pt[0] - n2[0] * H1 / 2., pt[1] - n2[1] * H1 / 2., pt[2] - n2[2] * H1 / 2.};
@@ -357,5 +398,5 @@ gLevelsetConrod::gLevelsetConrod(const double *pt, const double *dir1, const dou
   Ls = new gLevelsetCut(p2);
 }
 
-
+gLevelsetConrod::gLevelsetConrod(const gLevelsetConrod &lv):gLevelsetImproved(lv){}
 #endif
diff --git a/contrib/DiscreteIntegration/DILevelset.h b/contrib/DiscreteIntegration/DILevelset.h
index a8b0c28288..1983d76845 100644
--- a/contrib/DiscreteIntegration/DILevelset.h
+++ b/contrib/DiscreteIntegration/DILevelset.h
@@ -31,7 +31,9 @@ protected:
   int tag_; // must be greater than 0
 public:
   gLevelset() : tag_(-1) {}
+  gLevelset(const gLevelset &);
   virtual ~gLevelset(){}
+  virtual gLevelset * clone() const{printf("Error virtual fct called gLevelset::clone()");	return 0;}
   virtual double operator() (const double &x, const double &y, const double &z) const = 0;
   // inline double operator () (const SPoint3 &p) const {return this->operator()(p.x(),p.y(),p.z());}
   bool isInsideDomain (const double &x, const double &y, const double &z) const {return this->operator()(x,y,z) * insideDomain > 0.;}
@@ -76,6 +78,7 @@ class gLevelsetPrimitive : public gLevelset
 {
 public:
   gLevelsetPrimitive() : gLevelset() {}
+  gLevelsetPrimitive(const gLevelsetPrimitive &lv) : gLevelset(lv) {}
   gLevelsetPrimitive(int &tag) {
     if (tag < 1) {
       printf("Tag of the levelset (%d) must be greater than 0.\n", tag);
@@ -115,6 +118,9 @@ public:
   gLevelsetPlane (const double *pt, const double *norm, int &tag);
   // define the plane passing through the 3 points pt1,pt2,pt3 and with outward normal (pt1,pt2)x(pt1,pt3)
   gLevelsetPlane (const double *pt1, const double *pt2, const double *pt3, int &tag);
+  // copy constructor
+  gLevelsetPlane(const gLevelsetPlane &lv);
+  virtual gLevelset * clone() const{return new gLevelsetPlane(*this);}
   // return negative value inward and positive value outward
   virtual double operator() (const double &x, const double &y, const double &z) const
     {return a * x + b * y + c * z + d;} 
@@ -136,7 +142,9 @@ protected:
 public:
   gLevelsetQuadric() : gLevelsetPrimitive() {init(); }
   gLevelsetQuadric(int &tag) : gLevelsetPrimitive(tag) {init(); }
-  ~gLevelsetQuadric() {}
+  gLevelsetQuadric(const gLevelsetQuadric &);
+  
+  virtual ~gLevelsetQuadric() {}
   double operator () (const double &x, const double &y, const double &z) const;
   virtual int type() const = 0;
 };
@@ -145,6 +153,8 @@ class gLevelsetGenCylinder : public gLevelsetQuadric
 {
 public:
   gLevelsetGenCylinder (const double *pt, const double *dir, const double &R, int &tag);
+  gLevelsetGenCylinder (const gLevelsetGenCylinder& );
+  virtual gLevelset * clone() const{return new gLevelsetGenCylinder(*this);}
   int type() const {return GENCYLINDER;}
 };
 
@@ -152,6 +162,8 @@ class gLevelsetEllipsoid : public gLevelsetQuadric
 {
 public:
   gLevelsetEllipsoid (const double *pt, const double *dir, const double &a, const double &b, const double &c, int &tag);
+  gLevelsetEllipsoid (const gLevelsetEllipsoid& );
+  virtual gLevelset * clone() const{return new gLevelsetEllipsoid(*this);}
   int type() const {return ELLIPS;}
 };
 
@@ -159,6 +171,8 @@ class gLevelsetCone : public gLevelsetQuadric
 {
 public:
   gLevelsetCone (const double *pt, const double *dir, const double &angle, int &tag);
+  gLevelsetCone (const gLevelsetCone& );
+  virtual gLevelset * clone() const{return new gLevelsetCone(*this);}
   int type() const {return CONE;}
 };
 
@@ -167,6 +181,8 @@ class gLevelsetGeneralQuadric : public gLevelsetQuadric
 public:
   gLevelsetGeneralQuadric (const double *pt, const double *dir, const double &x2, const double &y2, const double &z2,
                            const double &z, const double &c, int &tag);
+  gLevelsetGeneralQuadric (const gLevelsetGeneralQuadric& );
+  virtual gLevelset * clone() const{return new gLevelsetGeneralQuadric(*this);}
   int type() const {return QUADRIC;}
 };
 
@@ -179,6 +195,7 @@ protected:
 public:
   gLevelsetTools () {}
   gLevelsetTools (std::vector<const gLevelset *> &p) {children = p;}
+  gLevelsetTools (const gLevelsetTools &);
   ~gLevelsetTools () {
     for(int i = 0; i < (int)children.size(); i++)
       delete children[i];
@@ -209,6 +226,8 @@ public:
     if(children.size() != 1) return tag_;
     return children[0]->getTag();
   }
+	
+  
 };
 
 class gLevelsetReverse : public gLevelset
@@ -235,7 +254,9 @@ public:
   gLevelsetCut (std::vector<const gLevelset *> &p) : gLevelsetTools(p) { }
   double choose (double d1, double d2) const {
     return (d1 > -d2) ? d1 : -d2; // greater of d1 and -d2
-  }
+  }	
+  gLevelsetCut(const gLevelsetCut &lv):gLevelsetTools(lv){}
+  virtual gLevelset * clone() const{return new gLevelsetCut(*this);}
   int type2() const {return CUT;}
 };
 
@@ -244,6 +265,9 @@ class gLevelsetUnion : public gLevelsetTools
 {
 public:
   gLevelsetUnion (std::vector<const gLevelset *> &p) : gLevelsetTools(p) { }
+  gLevelsetUnion(const gLevelsetUnion &lv):gLevelsetTools(lv){}
+  virtual gLevelset * clone() const{return new gLevelsetUnion(*this);}
+  
   double choose (double d1, double d2) const {
     return (d1 < d2) ? d1 : d2; // lesser of d1 and d2
   }
@@ -254,7 +278,10 @@ public:
 class gLevelsetIntersection : public gLevelsetTools
 {
 public:
-  gLevelsetIntersection (std::vector<const gLevelset *> &p) : gLevelsetTools(p) { }
+	gLevelsetIntersection (std::vector<const gLevelset *> &p) : gLevelsetTools(p) { }
+	gLevelsetIntersection(const gLevelsetIntersection &lv):gLevelsetTools(lv){}
+  virtual gLevelset * clone() const{return new gLevelsetIntersection(*this);}
+  
   double choose (double d1, double d2) const {
     return (d1 > d2) ? d1 : d2; // greater of d1 and d2
   }
@@ -285,6 +312,8 @@ class gLevelsetImproved : public gLevelset
 protected:
   gLevelset *Ls;
 public:
+  gLevelsetImproved(){}
+  gLevelsetImproved(const gLevelsetImproved &lv);
   double operator() (const double &x, const double &y, const double &z) const {return (*Ls)(x, y, z);}
   std::vector<const gLevelset *> getChildren() const { return Ls->getChildren(); }
   double choose (double d1, double d2) const { return Ls->choose(d1, d2); }
@@ -320,6 +349,8 @@ public:
   //                         face(pt1,pt5,pt8,pt4) : tag+5
   gLevelsetBox(const double *pt1, const double *pt2, const double *pt3, const double *pt4,
                const double *pt5, const double *pt6, const double *pt7, const double *pt8, int &tag);
+  gLevelsetBox(const gLevelsetBox &);
+  virtual gLevelset * clone() const{return new gLevelsetBox(*this);}
   int type() const {return BOX;}
 };
 
@@ -344,6 +375,8 @@ public:
   //                         plane face opposite to pt : tag+2
   //                         interior face :             tag+3
   gLevelsetCylinder (const double *pt, const double *dir, const double &R, const double &r, const double &H, int &tag);
+  gLevelsetCylinder(const gLevelsetCylinder &);
+  virtual gLevelset * clone() const{return new gLevelsetCylinder(*this);}
   int type() const {return CYLINDER;}
 };
 
@@ -379,6 +412,8 @@ public:
                    const double &H1, const double &H2, const double &H3,
                    const double &R1, const double &r1, const double &R2, const double &r2,
                    const double &L1, const double &L2, const double &E, int &tag);
+  gLevelsetConrod(const gLevelsetConrod &);
+  virtual gLevelset * clone() const{return new gLevelsetConrod(*this);}
   int type() const {return CONROD;}
 };
 
-- 
GitLab