next up previous contents
Next: Pigment Up: CSG Previous: ''fast'' Merge and Intersection,   Contents

CSG copy by reference

For the copy of the CSG only some basic information has to be stored for the copy: the transformation, possibly the texture. But the CSG member object do not have to be copied. This saves memory and allows extreme recursive structures.

Example scene: Cut menger sponge with recursion depth 6.

// C++ code

Object3D* make_menger(double length, int depth) {

    if (depth>0) {

        Object3D* piece = make_menger(length/3,depth-1);

        CSG* u = new CSG(CSG::UNION);

        Object3D* q = piece->duplicate();
        q->translate(Vector3(-length/3,-length/3,-length/3));
        u->addObject(q);

        q = piece->duplicate();
        q->translate(Vector3(-length/3,-length/3,length/3));
        u->addObject(q);

        q = piece->duplicate();
        q->translate(Vector3(-length/3,length/3,-length/3));
        u->addObject(q);

        q = piece->duplicate();
        q->translate(Vector3(-length/3,length/3,length/3));
        u->addObject(q);

        q = piece->duplicate();
        q->translate(Vector3(length/3,-length/3,-length/3));
        u->addObject(q);

        q = piece->duplicate();
        q->translate(Vector3(length/3,-length/3,length/3));
        u->addObject(q);

        q = piece->duplicate();
        q->translate(Vector3(length/3,length/3,-length/3));
        u->addObject(q);

        q = piece->duplicate();
        q->translate(Vector3(length/3,length/3,length/3));
        u->addObject(q);

        //

        q = piece->duplicate();
        q->translate(Vector3(-length/3,-length/3,0));
        u->addObject(q);

        q = piece->duplicate();
        q->translate(Vector3(length/3,-length/3,0));
        u->addObject(q);

        q = piece->duplicate();
        q->translate(Vector3(-length/3,length/3,0));
        u->addObject(q);

        q = piece->duplicate();
        q->translate(Vector3(length/3,length/3,0));
        u->addObject(q);

        //

        q = piece->duplicate();
        q->translate(Vector3(0,-length/3,-length/3));
        u->addObject(q);

        q = piece->duplicate();
        q->translate(Vector3(0,length/3,-length/3));
        u->addObject(q);

        q = piece->duplicate();
        q->translate(Vector3(0,-length/3,length/3));
        u->addObject(q);

        q = piece->duplicate();
        q->translate(Vector3(0,length/3,length/3));
        u->addObject(q);

        //

        q = piece->duplicate();
        q->translate(Vector3(-length/3,0,-length/3));
        u->addObject(q);

        q = piece->duplicate();
        q->translate(Vector3(length/3,0,-length/3));
        u->addObject(q);

        q = piece->duplicate();
        q->translate(Vector3(-length/3,0,length/3));
        u->addObject(q);

        q = piece;
        q->translate(Vector3(length/3,0,length/3));
        u->addObject(q);

        u->close();

        return u;

    } else
    {
        Object3D* o = new Box(-length/2*1.0001,length/2*1.0001);
        return o;
    }

}

Pigment3D* setUpScene_Menger() {

    Scene* s = new Scene();

    CSG* csg = new CSG(CSG::INTERSECT);

    Object3D* menger = make_menger(3,3);
    csg->addObject(menger);

    Plane *pl = new Plane(Vector3(0,1,0));
    pl->translate(Vector3(0,1.1,0));
    pl->rotate(Vector3(-45,-40,0));
    csg->addObject(pl);

    csg->setPigment(Pigment3DConstant(Colour5(.7,.7,.7,0,0)));
    csg->setFinish(Finish(0.03,0.3,0.6,1,5));
    csg->rotate(Vector3(11,23,0));
    csg->translate(Vector3(0,0,6));
    s->addObject(csg);

    PointLight* p = new PointLight(Vector3(0,10,-8),Colour3(1),s);
    s->addLight(p);

    PointLight* p2 = new PointLight(Vector3(-3,4,-6),Colour3(.5),s);
    s->addLight(p2);

    Material3D m = Material3D(new Texture3D(new Pigment3DConstant(Colour5(0)), new Finish(0.1,0.6,0,0,0)), new Interior() );
    s->setDefaultMaterial(m);

    s->object.prepareToRender();

    CameraPerspective* c = new CameraPerspective(s);

    return c;

};

// same in pov SDL

#macro menger(l,d)
 #if (d>0)
  #local p = menger(l/3,d-1)
  union{
  #declare ix=-1; #while(ix<2)
   #declare iy=-1; #while(iy<2)
    #declare iz=-1; #while(iz<2)
     #if ((ix!=0 & iy!=0) | (iy!=0 & iz!=0) | (ix!=0 & iz!=0))
      object{p translate <ix,iy,iz>*l/3}
     #end
    #declare iz=iz+1; #end
   #declare iy=iy+1; #end
  #declare ix=ix+1; #end
  }
 #else box{-l/2*1.0001,l/2*1.0001} #end
#end

intersection{
  object{menger(3,6)}
  plane{y,0 translate<0,1.1,0> rotate<-45,-40,0>}

  pigment{rgb .7}
  finish{ambient .03 diffuse 0.3 reflection .6 phong 1 phong_size 5}
  rotate<11,23,0>
  translate<0,0,6>
}

light_source{<0,10,-8>,1}
light_source{<-3,4,-6>,.5}

global_settings{
  max_trace_level 100
  adc_bailout 1/100
}
Don't try to render the pov code with POV-Ray. It would take tons of memory and months of render time. Different ways are needed to model this in POV-Ray.



Micha Riser 2002-10-24