• fullscreen
• attractor.pde
• control_ip5.pde
• kamara.pde
• regelwerk_mit_voxel.pde
• threepoint.pde
• toxic.pde
• ```ArrayList Dog=new ArrayList();
ArrayList Cat=new ArrayList();

float h;
PVector Craft;
class attractor extends Vec2D{
float A, B;
boolean C=true,run=true;
int counterChilds;
attractor(float tempA, float tempB)
{
super(tempA,tempB);
A=tempA;
B=tempB;
}
void drawattractor()
{
if (run)
{
if(C)
{
stroke(100,0,0);
fill(100,0,0);
}
else
{
stroke(255,0,0);
fill(255,0,0);
}
strokeWeight (1);
ellipse (A,B,2,2);
line (A, B, 0, A, B, 30);
}
}
}

class earthpoint extends Vec2D{
float A, B;
boolean C=true,run=true;
int counterChilds;
earthpoint(float tempA, float tempB)
{
super(tempA,tempB);
A=tempA;
B=tempB;
}
void drawearthpoint()
{
if(run)
{
if(C)
{
stroke(0,0,100);
fill(0,0,100);
}
else
{
stroke(0,0,255);
fill(0,0,255);
}
strokeWeight (1);
ellipse (A,B,2,2);
line (A, B, 0, A, B, 30);
}
}
}
void Hug (float x,float y)
{
float Craft=0;
float [] hoch=new float[Dog.size ()];
for (int i =0; i < Dog.size (); i=i+1)
{
attractor b = (attractor)Dog.get (i);
hoch[i]=0;
if(b.run)
{
PVector c=new PVector(b.A,b.B);
PVector d=new PVector(x,y);
PVector j= PVector.sub(c,d);
float f=j.mag();
float k=s5*f;
float g=k+s6;
hoch[i]=3/g;
}
}

for (int i =0; i < Dog.size (); i=i+1)
{
Craft=Craft+hoch[i];
}
h=Craft*s4;
}
```
```import controlP5.*;          // GUI
ControlP5 controlP5;
PMatrix3D currCameraMatrix;
PGraphics3D g3;
float s4=2,s5=0.03,s6=0.5,s13=150,gro=10,Npa=0;
boolean wireallow=false,hide=false;
float Listchoose=0;//<30 for Attractor, >30 false for Earthpoint
ListBox l;
ListBox m;
int lcounter=3,mcounter=1;

void setupGUI () {
g3 = (PGraphics3D)g;
controlP5 = new ControlP5(this);

controlP5.setColorForeground(85);
controlP5.setColorBackground(50);
controlP5.setColorLabel(0xFFFFFF);
controlP5.setColorValue(0);
controlP5.setColorActive(180);

controlP5.addSlider("Elementsize", 5, 20, 10, 10, 10, 200, 15);
controlP5.addSlider("Grenze", 100, 1000,150, 10, 40, 200, 15);
controlP5.addSlider("Hoch", 0, 10, 2, 10, 70, 200, 15);
controlP5.addSlider("Kwert", 0.005, 0.1, 0.03, 10, 100, 200,15);
controlP5.addSlider("Translationswert", 0, 2, 0.5, 10, 130, 200, 15);
/////////////////////
//voxel
///////////////////////
//attractor wahlen
l.setItemHeight(15);
l.setBarHeight(15);

l.captionLabel().toUpperCase(true);
l.captionLabel().set("Attractor List");
l.captionLabel().style().marginTop = 3;
l.valueLabel().style().marginTop = 3;
for(int i=0;i<3;i++) {
}

//Earthpoint wahlen
m.setItemHeight(15);
m.setBarHeight(15);

m.captionLabel().toUpperCase(true);
m.captionLabel().set("Earthpoint List");
m.captionLabel().style().marginTop = 3;
m.valueLabel().style().marginTop = 3;
for(int i=0;i<1;i++) {
}

}
void controlEvent(ControlEvent theEvent) {
if(theEvent.isGroup()){
Listchoose=theEvent.group().value();
println(Listchoose);

}
if(theEvent.isController()) {
if(theEvent.controller().name()=="Hide/Show Reactor") {
hide=!hide;
}
if(theEvent.controller().name()=="Voxelize") {
voxelallow=!voxelallow;

if (voxelallow&&Lauf){
controlP5.controller("RUN or Stop").setValue(0);
}
if (voxelallow==true){
boundd();
setupStructure();
for (int i =0; i < Flaeche.size (); i=i+1)
{
threepoint b = (threepoint)Flaeche.get (i);
b.updatepos();
b.sendmesh ();
}
voxelizemesh();
}
}
if(theEvent.controller().name()=="RUN or Stop") {
Lauf=!Lauf;
if (Lauf&&voxelallow){
controlP5.controller("Voxelize").setValue(0);

//controlP5.controller("Voxelize").setValue(0);
}
}
{
if (Listchoose<30)
{
lcounter++;

}
if (Listchoose>=30)
{
mcounter++;
}

}
if(theEvent.controller().name()=="Rmv Reactor")
{
if (Listchoose<30)
{
int n=int(Listchoose+1);
l.removeItem("attractor "+n);
attractor b = (attractor)Dog.get (int(Listchoose));
b.run=false;
}
if (Listchoose>=30)
{
int n=int(Listchoose-29);
m.removeItem("earthpoint "+n);
earthpoint b = (earthpoint)Cat.get (int(Listchoose-30));
b.run=false;
}

}
}
}

void drawGUI() {
currCameraMatrix = new PMatrix3D(g3.camera);
camera();
controlP5.draw();
if(!hide){
if (Listchoose>=30)
{
fill(0,0,180);
text("Earthpoints make the nearest element low till the ground",700,45);
}
if (Listchoose<30)
{
fill(180,0,0);
text("Attractors pull the area arround which higher",700,45);
}
fill(180);
text("choose in the lists and use keyboard W S A D to move the reactor",700,60);
text("plz wait n push nothing when the computer is runing for the voxelprocess ",700,75);
}
g3.camera = currCameraMatrix;
}

void Elementsize (float h) {
gro = h;
}
void Hoch (float h) {
s4 = h;
}
void Kwert (float h) {
s5 = h;
}
void Translationswert (float h) {
s6 = h;
}

void Grenze (float h) {
s13 = h;
}

void Nordpunkt (float h) {
Npa = PI*(h-0.5);
}

/////////////////////////////////

void Wireform (boolean h) {
wireallow = h;
}

```
```void setupCamera () {
//PeasyCam Variablen
cam = new PeasyCam(this, 150);
cam.setMinimumDistance(10);
cam.setMaximumDistance(1000);
cam.setRightDragHandler(null);

setPerpetiveView() ;
topView();

}

void drawCamera () {

if (controlP5.window(this).isMouseOver()) {
cam.setActive(false);
}
else {
cam.setActive(true);
}

hint(ENABLE_DEPTH_TEST);
}
void topView() {
cam.setRotations(0, 0, PI); // pitch,  yaw, roll rotations are applied in that order
}

void setPerpetiveView() {
perspective(PI/3.0, (float)width/height, 1, 100000);
}
void keyPressed()
{
if (key == 'w' || key == 'W')
{
if (Listchoose<30)
{
attractor tmp=(attractor)Dog.get (int(Listchoose));
tmp.B++;
}
else
{
earthpoint tmp=(earthpoint)Cat.get (int(Listchoose-30));
tmp.B++;
}
}
if (key == 's' || key == 'S')
{
if (Listchoose<30)
{
attractor tmp=(attractor)Dog.get (int(Listchoose));
tmp.B--;
}
else
{
earthpoint tmp=(earthpoint)Cat.get (int(Listchoose-30));
tmp.B--;
}
}
if (key == 'a' || key == 'A')
{
if (Listchoose<30)
{
attractor tmp=(attractor)Dog.get (int(Listchoose));
tmp.A++;
}
else
{
earthpoint tmp=(earthpoint)Cat.get (int(Listchoose-30));
tmp.A++;
}
}
if (key == 'D' || key == 'd')
{
if (Listchoose<30)
{
attractor tmp=(attractor)Dog.get (int(Listchoose));
tmp.A--;
}
else
{
earthpoint tmp=(earthpoint)Cat.get (int(Listchoose-30));
tmp.A--;
}
}

if (key == 'r' || key == 'R')
{
Punkt=new ArrayList();
Linie=new ArrayList();
Flaeche=new ArrayList();
Vec3D A = new Vec3D (0, 0, 0);
Vec3D B = new Vec3D (gro, 0, 0);
Vec3D C = new Vec3D (gro/2, gro/2*sqrt(3), 0);
}

}
```
```
import toxi.volume.*;
import toxi.math.conversion.*;
import toxi.geom.*;
import toxi.math.*;
import toxi.geom.mesh2d.*;
import toxi.util.datatypes.*;
import toxi.util.events.*;
import toxi.geom.mesh.subdiv.*;
import toxi.geom.mesh.*;
import toxi.math.waves.*;
import toxi.util.*;
import toxi.math.noise.*;
import peasy.*;

PeasyCam cam;
boolean voxelallow=false;
ArrayList Punkt=new ArrayList();
ArrayList Linie=new ArrayList();
ArrayList Flaeche=new ArrayList();
boolean reception,Lauf=false;
float Nord=1;
void setup()
{
size (1280, 700, P3D);
gfx = new ToxiclibsSupport(this);
setupGUI ();
smooth();
strokeWeight (1);
stroke(255);
Vec3D A = new Vec3D (0, 0, 0);
Vec3D B = new Vec3D (gro, 0, 0);
Vec3D C = new Vec3D (gro/2, gro/2*sqrt(3), 0);

setupCamera ();
}
void draw()
{

///////////////

reception=true;
Vec3D Cpunkt=new Vec3D();
background (0);
float counterboard;
drawCamera ();
Vec3D Npunkt=new Vec3D (-sin(Npa)*s13/2,cos(Npa)*s13/2,0);
///////////////
if(!hide)
{
noFill();
stroke(150);
strokeWeight (1);
ellipse (0,0,s13,s13);
fill(150);
ellipse (-sin(Npa)*s13/2,cos(Npa)*s13/2,3,3);
}
//////////////draw district
if (Lauf==true)
{
int randomLinie= int (random ( Linie.size ()));
int randomLinie2= int (random ( Linie.size ()));
twopoint MyLinie = (twopoint)Linie.get (randomLinie);
twopoint MyLinie2nd = (twopoint)Linie.get (randomLinie2);
Vec3D midMyLinie=new Vec3D (MyLinie.A.x/2+MyLinie.B.x/2,MyLinie.A.y/2+MyLinie.B.y/2,0);
Vec3D midMyLinie2nd=new Vec3D (MyLinie2nd.A.x/2+MyLinie2nd.B.x/2,MyLinie2nd.A.y/2+MyLinie2nd.B.y/2,0);
float distM1=Npunkt.distanceTo(midMyLinie);
float distM2=Npunkt.distanceTo(midMyLinie2nd);
if (distM1>distM2&&Nord>0)
{
MyLinie=(twopoint)Linie.get (randomLinie2);
}
Nord++;
if (Nord==2)
{
Nord=0;
}

/////////////richtungcontroler
if  (MyLinie.counterChilds<2)
{
//////////////////////
for(int i=0;i<Flaeche.size();i=i+1)
{
threepoint a=(threepoint)Flaeche.get(i);
if (MyLinie.A==a.A||MyLinie.A==a.B||MyLinie.A==a.C)
{
if (MyLinie.B==a.A||MyLinie.B==a.B||MyLinie.B==a.C)
{
if (a.A!=MyLinie.A&&a.A!=MyLinie.B)
{
Cpunkt=new Vec3D (a.A.x,a.A.y,a.A.z);
}
else if (a.B!=MyLinie.A&&a.B!=MyLinie.B)
{
Cpunkt=new Vec3D (a.B.x,a.B.y,a.B.z);
}
else
{
Cpunkt=new Vec3D (a.C.x,a.C.y,a.C.z);
}

}
}
}
/////////////////////
Vec3D richtungsVektor1= MyLinie.A.sub(Cpunkt);
Vec3D richtungsVektor2= MyLinie.B.sub(Cpunkt);
////////////////////////
Vec3D O=new Vec3D (0,0,0);
if (drittepunkt.distanceTo(O)<=s13/2)
{
for(int i=0;i<Punkt.size();i=i+1)
{
onepoint a=(onepoint)Punkt.get(i);
if (a.A.distanceTo(MyLinie.A)<1||a.A.distanceTo(MyLinie.B)<1||a.A.distanceTo(drittepunkt)<1)
{
if (a.A.distanceTo(drittepunkt)<1)
{
drittepunkt=a.A;
}
float d= a.A.distanceTo(Npunkt);
counterboard=map(d,0,s13,4,7);
if (a.counterChilds>counterboard-1)
{
reception=false;
}
}
}
/////////////////////
if (reception==true)
{
MyLinie.counterChilds++;
for(int i=0;i<Punkt.size();i=i+1)
{
onepoint a=(onepoint)Punkt.get(i);
if (a.A.distanceTo(MyLinie.A)<1||a.A.distanceTo(MyLinie.B)<1||a.A.distanceTo(drittepunkt)<1)
{
a.counterChilds++;
//println(a.counterChilds);
}
}
//////////////
Vec3D a1=new Vec3D(MyLinie.A.x,MyLinie.A.y,0);
Vec3D b1=new Vec3D(MyLinie.B.x,MyLinie.B.y,0);
Vec3D c1=new Vec3D(drittepunkt.x,drittepunkt.y,0);
///////////////
boolean cat=true;
for(int i=0;i<Punkt.size();i=i+1)
{
onepoint a=(onepoint)Punkt.get(i);
if (a.A==drittepunkt)
{
cat=false;
}
}
if (cat=true)
{
}
else
{
cat=true;
for(int i=0;i<Linie.size();i=i+1)
{
twopoint MyLinie1 = (twopoint)Linie.get (i);
if (MyLinie1.A==MyLinie.A&&MyLinie1.B==drittepunkt)
{
MyLinie1.counterChilds++;
}
else if (MyLinie1.B==MyLinie.A&&MyLinie1.A==drittepunkt)
{
MyLinie1.counterChilds++;
}
else
{
}
}
for(int i=0;i<Linie.size();i=i+1)
{
twopoint MyLinie2 = (twopoint)Linie.get (i);
if (MyLinie2.A==MyLinie.B&&MyLinie2.B==drittepunkt)
{
MyLinie2.counterChilds++;
}
else if (MyLinie2.B==MyLinie.B&&MyLinie2.A==drittepunkt)
{
MyLinie2.counterChilds++;
}
else
{
}
}
}

}
}
}
}
stroke (255);
if (!hide)
{
for (int i =0; i < Dog.size (); i=i+1)
{
attractor b = (attractor)Dog.get (i);
if (i==Listchoose)
{
b.C=false;
}
b.drawattractor ();
b.C=true;
}
for (int i =0; i < Cat.size (); i=i+1)
{
earthpoint b = (earthpoint)Cat.get (i);
if (i==Listchoose-30)
{
b.C=false;
}
b.drawearthpoint ();
b.C=true;
}
}
if (!voxelallow){
for (int i =0; i < Flaeche.size (); i=i+1)
{
threepoint b = (threepoint)Flaeche.get (i);
b.updatepos();
b.drawthreepoint ();
}
}

//draw voxel
if (voxelallow){
if (wireallow){
noFill();
strokeWeight(1);
stroke(255);
gfx.mesh(mesh);
}
else {
fill(255);
noStroke();
lights();
gfx.mesh(mesh);
noLights();
}
}

drawGUI();
}
```
```
class threepoint {
float h1,h2,h3,h4,h5,h6,h7;
Vec2D A2d,B2d,C2d;
boolean Que;

//int counterChilds;
threepoint(Vec3D tempA, Vec3D tempB,Vec3D tempC)
{
A=tempA;
B=tempB;
C=tempC;
// counterChilds=1;
D=new  Vec3D(A.x/3+B.x/3+C.x/3,A.y/3+B.y/3+C.y/3,0);

}
void updatepos()
{
Que=false;
fill(127,50);
Hug (A.x,A.y);
h1=h;
Apos=new Vec3D(A.x,A.y,h1);
Hug (B.x,B.y);
h2=h;
Bpos=new Vec3D(B.x,B.y,h2);
Hug (C.x,C.y);
h3=h;
Cpos=new Vec3D(C.x,C.y,h3);
Np=new Vec3D (-sin(Npa)*s13/2,cos(Npa)*s13/2,0);
Hug (A.x/3+B.x/3+C.x/3,A.y/3+B.y/3+C.y/3);
h4=h;
D=new Vec3D (A.x/3+B.x/3+C.x/3,A.y/3+B.y/3+C.y/3,0);
Dpos=new Vec3D(D.x,D.y,h4);
float juli=D.distanceTo(Np);
//float s=0.05;
float s=0.5*juli/s13;
CD=D.sub(C);
CD.scaleSelf(s);
Hug (E.x,E.y);
h5=h;
Epos=new Vec3D(E.x,E.y,h5);
Hug (F.x,F.y);
h6=h;
Fpos=new Vec3D(F.x,F.y,h6);
BD=D.sub(B);
BD.scaleSelf(s);
Hug (G.x,G.y);
h7=h;
Gpos=new Vec3D(G.x,G.y,h7);
A2d=new Vec2D (A.x,A.y);
B2d=new Vec2D (B.x,B.y);
C2d=new Vec2D (C.x,C.y);
Polygon2D Thisone=new Polygon2D(A2d,B2d,C2d);
for(int i=0;i<Cat.size();i=i+1){
earthpoint b=(earthpoint)Cat.get(i);
if (b.run)
{
Vec2D tmp=new Vec2D(b.A,b.B);
if (Thisone.containsPoint( tmp )){
//Dpos=new Vec3D(D.x,D.y,0);
Epos=new Vec3D(E.x,E.y,h5/2);
Fpos=new Vec3D(F.x,F.y,h6/2);
Gpos=new Vec3D(G.x,G.y,h7/2);
Que=true;
}
}
}

}

void drawthreepoint()
{
stroke(255);
strokeWeight (1);
fill(255,80);
if(wireallow)
{
noFill();
}
if (!Que)
{
beginShape();
vertex(A.x,A.y,h1);
vertex(E.x,E.y,h5);
vertex(B.x,B.y,h2);
vertex(D.x,D.y,h4);
vertex(A.x,A.y,h1);
endShape();
//////////AB
beginShape();
vertex(C.x,C.y,h3);
vertex(F.x,F.y,h6);
vertex(B.x,B.y,h2);
vertex(D.x,D.y,h4);
vertex(C.x,C.y,h3);
endShape();
/////////////BC
beginShape();
vertex(C.x,C.y,h3);
vertex(G.x,G.y,h7);
vertex(A.x,A.y,h1);
vertex(D.x,D.y,h4);
vertex(C.x,C.y,h3);
endShape();
noFill();
beginShape();
stroke(100);
vertex(A.x,A.y,h1);
vertex(B.x,B.y,h2);
vertex(C.x,C.y,h3);
vertex(A.x,A.y,h1);
endShape();
}
if(Que)
{
Vec3D D0=new Vec3D(D.x,D.y,D.z);
beginShape();
gfx.vertex(Apos);
gfx.vertex(Epos);
gfx.vertex(D0);
gfx.vertex(Gpos);
gfx.vertex(Apos);
endShape();
beginShape();
gfx.vertex(Bpos);
gfx.vertex(Epos);
gfx.vertex(D0);
gfx.vertex(Fpos);
gfx.vertex(Bpos);
endShape();
beginShape();
gfx.vertex(Cpos);
gfx.vertex(Gpos);
gfx.vertex(D0);
gfx.vertex(Fpos);
gfx.vertex(Cpos);
endShape();
gfx.line(Apos,Dpos);
gfx.line(Bpos,Dpos);
gfx.line(Cpos,Dpos);
}
}
void sendmesh ()
{
Line3D segment;
//    segment=new Line3D (Apos,Bpos);
//    builder.createLattice(brush, segment, 1);
//    segment=new Line3D (Cpos,Bpos);
//    builder.createLattice(brush, segment, 1);
//    segment=new Line3D (Cpos,Apos);
//    builder.createLattice(brush, segment, 1);
segment=new Line3D (Dpos,Apos);
builder.createLattice(brush, segment, 1);
segment=new Line3D (Dpos,Bpos);
builder.createLattice(brush, segment, 1);
segment=new Line3D (Dpos,Cpos);
builder.createLattice(brush, segment, 1);
segment=new Line3D (Apos,Epos);
builder.createLattice(brush, segment, 1);
segment=new Line3D (Bpos,Epos);
builder.createLattice(brush, segment, 1);
segment=new Line3D (Apos,Gpos);
builder.createLattice(brush, segment, 1);
segment=new Line3D (Cpos,Gpos);
builder.createLattice(brush, segment, 1);
segment=new Line3D (Bpos,Fpos);
builder.createLattice(brush, segment, 1);
segment=new Line3D (Cpos,Fpos);
builder.createLattice(brush, segment, 1);
if (Que){
segment=new Line3D (D,Fpos);
builder.createLattice(brush, segment, 1);
segment=new Line3D (D,Epos);
builder.createLattice(brush, segment, 1);
segment=new Line3D (D,Gpos);
builder.createLattice(brush, segment, 1);
segment=new Line3D (D,E);
builder.createLattice(brush, segment, 1);
segment=new Line3D (D,G);
builder.createLattice(brush, segment, 1);
segment=new Line3D (D,F);
builder.createLattice(brush, segment, 1);
}
}
}

class twopoint extends Line3D{
Vec3D A, B;
int counterChilds;
twopoint(Vec3D tempA, Vec3D tempB)
{
super(tempA,tempB);
A=tempA;
B=tempB;
counterChilds=1;
}

}

class onepoint
{
Vec3D A;
int counterChilds=1;
onepoint(Vec3D tempA)
{
A=tempA;
}

}

```
```import toxi.geom.*;
import toxi.geom.mesh.*;
import toxi.volume.*;
import toxi.color.*;
import toxi.processing.*;

int VOXEL_RES=64;
int VOXEL_STROKE_WEIGHT=7;
int SPHERE_RES=8;
int SMOOTH_ITER=6;
ToxiclibsSupport gfx;
WETriangleMesh mesh;
int voxelRes = 300;
AABB bounds3D;
MeshLatticeBuilder builder;
VolumetricSpace volume;
VolumetricBrush brush;

boolean isWireframe;
void boundd()
{
bounds3D = new AABB();

Vec3D c1=new Vec3D(75,75,50);
Vec3D c2=new Vec3D(-75,-75,-50);

bounds3D.growToContainPoint(c1);
bounds3D.growToContainPoint(c2);

}
void setupStructure()
{
mesh = new WETriangleMesh();
Vec3D extent = bounds3D.getExtent();
builder = new MeshLatticeBuilder(extent.scale(2),voxelRes, voxelRes, voxelRes/2, new FloatRange(1, 1));
builder.setInputBounds(new AABB(bounds3D, extent.scale(1f)));
volume = builder.getVolume();
brush = new BoxBrush(volume, 0.5f);
brush.setMode(VolumetricBrush.MODE_PEAK);
}

void voxelizemesh()
{
volume.closeSides();
new HashIsoSurface(volume).computeSurfaceMesh(mesh, 1f);
new LaplacianSmooth().filter(mesh, 10);
}

```

### tweaks (0)

This sketch is running as Java applet, exported from Processing.

Report Sketch

Report for inappropriate content

Your have successfully reported the sketch. Thank you very much for helping to keep OpenProcessing clean and tidy :)

## regelwerk_mit_voxel&Toy; for architectrue

5

a further step by far,it turn to be a toy for architecture,thanks for the Toxiclibs Lib(prerelease 0021), don forget to play with full window, using w s a d to move the reactors, then voxelize the structrue,i m looking forward to the next coming version. STLexport will also be with the next one.sry for the low quality shown by P3D,u can download it and change to opengl.

for more clear fotos
http://www.flickr.com/photos/80135466@N05/sets/72157630012913349/

for video from the project
https://vimeo.com/43665519

@zl_li

Nice sketch, I would just suggest to change the font rendering mode to SCREEN mode (via fontMode(SCREEN)) in applet's P3D.. for better readability. Thanks for sharing!
Zhili Li
14 Jun 2012
thx for the sugguestion Kof , i tried to put fontMode(SCREEN) in my setup();but it said that fontMode does not exist, so,where should i put tat?
"Tudd"
15 Jun 2012
try textMode().
Zhili Li
15 Jun 2012
tried,but not works on the font inside the controlp5,but thank u for ur suggestion
Ok, so you are probably using some more recent version of Processing, some of the Alpha pre-releases.. version 2.0a1 (REV 0200) already drop support for this command.

k.
Zhili Li
18 Jun 2012
oh i c, thanks Kof, i tried 2.0 and the code doesnt work(seems not so match with the latest version from controlp5), so i have to look up wat hat been changed in the last version so that i can rewrite the part which need to be replaced。
You need to login/register to comment.