/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOUSE. See the GNU
 * General Public License for more details.
 *
 * You should have recieved a copy of the GNU General Public License
 * along with this program; if not write to the Free Software
 * Foundation, inc., 59 Temple Place, Suite 330, Boston MA 02111-1307
 * USA
 */
package j3d;
import java.awt.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.tree.*;
import java.io.*;
import gui.*;
import javax.swing.*;
import java.awt.event.*;
/**
 * Insert the type's description here.
 *
 * @author: Yuriy Mikhaylovskiy
 */

public class _SurfDir implements _Object, Serializable{
  private Canvas3D J3D;
  private PreProcessor PreP;
  private Vector nodesDB = new Vector();
  private Vector elementsDB = new Vector();
  public _Object curve1,curve2;
  private _Node[][] nodes;
  private int M,N;
  public float msh_size;
  public float thickness;
  public Material material = null;
  public Color color = Color.black;
  private String Id;
  public boolean selected = false;
  private String msh_name = "Contact_Triangle";
  private int msh_type = Canvas3D.MESH_Contact_Triangle;
  public JTextField tfcurve1,tfcurve2,tfsize,tft;
  public JComboBox cb_msh_type,cb_mat;
  public void mesh(int type, float size){}


  private void writeObject(ObjectOutputStream out)  throws IOException{
    out.writeObject(nodesDB);
    out.writeObject(elementsDB);
    out.writeObject(curve1);
    out.writeObject(curve2);
    out.writeFloat(msh_size);
    out.writeFloat(thickness);
    out.writeObject(material);
    out.writeObject(color);
    out.writeObject(msh_name);
    out.writeInt(msh_type);
  }
  private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
    nodesDB = (Vector)in.readObject();
    elementsDB = (Vector)in.readObject();
    curve1 = (_Object)in.readObject();
    curve2 = (_Object)in.readObject();
    msh_size = in.readFloat();
    thickness = in.readFloat();
    material = (Material)in.readObject();
    color = (Color)in.readObject();
    selected = false;
    msh_name = (String)in.readObject();
    msh_type = in.readInt();
    for(int i=0; i<nodesDB.size(); i++) ((_Object)nodesDB.elementAt(i)).set_Id(i+"");
    for(int i=0; i<elementsDB.size(); i++) ((_Object)elementsDB.elementAt(i)).set_Id(i+"");
  }

  public boolean delete(){
    for(int i=0; i<elementsDB.size(); i++){
      if(((_Object)elementsDB.elementAt(i)).isSelected()){
        elementsDB.removeElementAt(i);
        i--;
      }
    }
    for(int i=0; i<nodesDB.size(); i++){
      _Node nd = (_Node)nodesDB.elementAt(i);
      if(nd.isSelected()){
        boolean using = false;
        for(int j=0; j<elementsDB.size(); j++){
          _Node[] nds = ((_Object)elementsDB.elementAt(j)).get_Nodes();
          for(int k=0; k<nds.length; k++){
            if(nds[k].equals(nd))using=true;
          }
        }
        if(!using){
          nodesDB.removeElementAt(i);
          i--;
        }
      }
    }
    return selected;
  }



  public _SurfDir(_Object c1, _Object c2, float msize, int mtype, Material m, float th){
    msh_type=mtype;
    msh_size=msize;
    curve1=c1; curve2=c2; material=m;
    thickness=th;
    reset();
  }
  public _SurfDir(_Object c1, _Object c2, float s, int t){
    this(c1,c2,s,t,null,1);
  }
  public _SurfDir(_Object c1, _Object c2, float s, int t, float th){
    this(c1,c2,s,t,null,th);
  }

  public void reset(){
    nodesDB = new Vector();
    elementsDB = new Vector();
    if(msh_type==Canvas3D.MESH_Contact_Triangle)msh_name = "Contact_Triangle";
    else if(msh_type==Canvas3D.MESH_Shell_C0_3)msh_name = "Shell_C0_3";
    else if(msh_type==Canvas3D.MESH_Shell_BT_4)msh_name = "Shell_BT_4";
    if(curve1 instanceof _Line){
      _Line ln = (_Line)curve1;
      M=1+(int)Math.round(Math.sqrt((ln.x1-ln.x2)*(ln.x1-ln.x2)+(ln.y1-ln.y2)*(ln.y1-ln.y2)+(ln.z1-ln.z2)*(ln.z1-ln.z2))/msh_size);
      if(M==1)M++;
    }else if(curve1 instanceof _NurbCurve){
      _NurbCurve ln = (_NurbCurve)curve1;
      float len = 0;
      _CtrlPoint[] cp = ln.controlPoints;
      for(int i=0; i<cp.length-1; i++)   len += (float)Math.sqrt((cp[i].x-cp[i+1].x)*(cp[i].x-cp[i+1].x)+(cp[i].y-cp[i+1].y)*(cp[i].y-cp[i+1].y)+(cp[i].z-cp[i+1].z)*(cp[i].z-cp[i+1].z));
      len=len/(cp.length-1)/msh_size;
      _NurbCurve nc = new _NurbCurve(cp,(int)len*cp.length,color);
      M=nc.mesh.length;
    }else if(curve1 instanceof _PLine){
      _PLine ln = (_PLine)curve1;
      M=0;
      float[] p1,p2;
      for(int i=0; i<ln.nodes.length-1; i++){
        p1 = ln.nodes[i];
        p2 = ln.nodes[i+1];
        int MM=(int)Math.round(Math.sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2]))/msh_size);
        if(MM==0)M++; else M+=MM;
      }
      p1 = ln.nodes[0];
      p2 = ln.nodes[ln.nodes.length-1];
      if(ln.close && !(p1[0]==p2[0] && p1[1]==p2[1] && p1[2]==p2[2])){
        int MM=(int)Math.round(Math.sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2]))/msh_size);
        if(MM==0)M++; else M+=MM;
      }
      M++;
    }
    if(curve2 instanceof _Line){
      _Line ln = (_Line)curve2;
      N=1+(int)Math.round(Math.sqrt((ln.x1-ln.x2)*(ln.x1-ln.x2)+(ln.y1-ln.y2)*(ln.y1-ln.y2)+(ln.z1-ln.z2)*(ln.z1-ln.z2))/msh_size);
      if(N==1)N++;
    }else if(curve2 instanceof _NurbCurve){
      _NurbCurve ln = (_NurbCurve)curve2;
      float len = 0;
      _CtrlPoint[] cp = ln.controlPoints;
      for(int i=0; i<cp.length-1; i++)   len += (float)Math.sqrt((cp[i].x-cp[i+1].x)*(cp[i].x-cp[i+1].x)+(cp[i].y-cp[i+1].y)*(cp[i].y-cp[i+1].y)+(cp[i].z-cp[i+1].z)*(cp[i].z-cp[i+1].z));
      len=len/(cp.length-1)/msh_size;
      _NurbCurve nc = new _NurbCurve(cp,(int)len*cp.length,color);
      N=nc.mesh.length;
    }else if(curve2 instanceof _PLine){
      _PLine ln = (_PLine)curve2;
      N=0;
      float[] p1,p2;
      for(int i=0; i<ln.nodes.length-1; i++){
        p1 = ln.nodes[i];
        p2 = ln.nodes[i+1];
        int NN=(int)Math.round(Math.sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2]))/msh_size);
        if(NN==0)N++; else N+=NN;
      }
      p1 = ln.nodes[0];
      p2 = ln.nodes[ln.nodes.length-1];
      if(ln.close && !(p1[0]==p2[0] && p1[1]==p2[1] && p1[2]==p2[2])){
        int NN=(int)Math.round(Math.sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2]))/msh_size);
        if(NN==0)N++; else N+=NN;
      }
      N++;
    }
    nodes = new _Node[M][N];
    //---------------------------------------
    //System.out.println("Nodes - "+M*N);
    //---------------------------------------
    if(curve1 instanceof _Line){
      _Line ln = (_Line)curve1;
      float len = (float)Math.sqrt((ln.x1-ln.x2)*(ln.x1-ln.x2)+(ln.y1-ln.y2)*(ln.y1-ln.y2)+(ln.z1-ln.z2)*(ln.z1-ln.z2))/msh_size;
      float dl = len/(M-1);
      for(int i=0; i<M; i++){
        float delta = i*dl/(len-i*dl);
        float x = (ln.x1+delta*ln.x2)/(1+delta);
        float y = (ln.y1+delta*ln.y2)/(1+delta);
        float z = (ln.z1+delta*ln.z2)/(1+delta);
        nodes[i][0]=new _Node(x,y,z){
          public String get_Id(){ return Id+"."+super.get_Id(); }
        };
      }
      _Node nd = new _Node(ln.x2,ln.y2,ln.z2){
        public String get_Id(){ return Id+"."+super.get_Id(); }
      };
      nd.set_Id((M-1)+"");
      nodes[M-1][0]=nd;
    }else if(curve1 instanceof _NurbCurve){
      _NurbCurve ln = (_NurbCurve)curve1;
      float len = 0;
      _CtrlPoint[] cp = ln.controlPoints;
      for(int i=0; i<cp.length-1; i++)   len += (float)Math.sqrt((cp[i].x-cp[i+1].x)*(cp[i].x-cp[i+1].x)+(cp[i].y-cp[i+1].y)*(cp[i].y-cp[i+1].y)+(cp[i].z-cp[i+1].z)*(cp[i].z-cp[i+1].z));
      len=len/(cp.length-1)/msh_size;
      _NurbCurve nc = new _NurbCurve(cp,(int)len*cp.length,color);
      for(int i=0; i<M; i++){
        _Point p = nc.mesh[i];
        nodes[i][0]=new _Node(p.x,p.y,p.z){
          public String get_Id(){ return Id+"."+super.get_Id(); }
        };
      }
    }else if(curve1 instanceof _PLine){
      _PLine ln = (_PLine)curve1;
      int k=0;
      float[] p1,p2;
      for(int i=0; i<ln.nodes.length-1; i++){
        p1 = ln.nodes[i];
        p2 = ln.nodes[i+1];
        float len = (float)Math.sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2]));
        int MM=(int)Math.round(len/msh_size);
        if(MM==0)MM=1;
        float dl = len/MM;
        for(int j=0; j<MM; j++){
          float delta = j*dl/(len-j*dl);
          float x = (p1[0]+delta*p2[0])/(1+delta);
          float y = (p1[1]+delta*p2[1])/(1+delta);
          float z = (p1[2]+delta*p2[2])/(1+delta);
          nodes[k][0]=new _Node(x,y,z){
            public String get_Id(){ return Id+"."+super.get_Id(); }
          };
          k++;
        }
      }
      p2 = ln.nodes[0];
      p1 = ln.nodes[ln.nodes.length-1];
      if(ln.close && !(p1[0]==p2[0] && p1[1]==p2[1] && p1[2]==p2[2])){
        float len = (float)Math.sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2]));
        int MM=(int)Math.round(len/msh_size);
        if(MM==0)MM=1;
        float dl = len/MM;
        for(int j=0; j<MM; j++){
          float delta = j*dl/(len-j*dl);
          float x = (p1[0]+delta*p2[0])/(1+delta);
          float y = (p1[1]+delta*p2[1])/(1+delta);
          float z = (p1[2]+delta*p2[2])/(1+delta);
          nodes[k][0]=new _Node(x,y,z){
            public String get_Id(){ return Id+"."+super.get_Id(); }
          };
          k++;
        }
        nodes[M-1][0]=new _Node(p2[0],p2[1],p2[2]){
          public String get_Id(){ return Id+"."+super.get_Id(); }
        };
      } else {
        p1 = ln.nodes[ln.nodes.length-1];
        nodes[M-1][0]=new _Node(p1[0],p1[1],p1[2]){
          public String get_Id(){ return Id+"."+super.get_Id(); }
        };
      }
    }
    if(curve2 instanceof _Line){
      _Line ln = (_Line)curve2;
      float len = (float)Math.sqrt((ln.x1-ln.x2)*(ln.x1-ln.x2)+(ln.y1-ln.y2)*(ln.y1-ln.y2)+(ln.z1-ln.z2)*(ln.z1-ln.z2))/msh_size;
      float dx = (ln.x2-ln.x1)/len;
      float dy = (ln.y2-ln.y1)/len;
      float dz = (ln.z2-ln.z1)/len;
      for(int i=0; i<M; i++){
        for(int j=1; j<N; j++){
          nodes[i][j]=new _Node(nodes[i][0].x+j*len/(N-1)*dx,nodes[i][0].y+j*len/(N-1)*dy,nodes[i][0].z+j*len/(N-1)*dz){
            public String get_Id(){ return Id+"."+super.get_Id(); }
          };
        }
      }
    }else if(curve2 instanceof _NurbCurve){
      _NurbCurve ln = (_NurbCurve)curve2;
      float len = 0;
      _CtrlPoint[] cp = ln.controlPoints;
      for(int i=0; i<cp.length-1; i++)   len += (float)Math.sqrt((cp[i].x-cp[i+1].x)*(cp[i].x-cp[i+1].x)+(cp[i].y-cp[i+1].y)*(cp[i].y-cp[i+1].y)+(cp[i].z-cp[i+1].z)*(cp[i].z-cp[i+1].z));
      len=len/(cp.length-1)/msh_size;
      _NurbCurve nc = new _NurbCurve(cp,(int)len*cp.length,color);
      for(int i=0; i<M; i++){
        for(int j=1; j<N; j++){
          nodes[i][j]=new _Node(nodes[i][j-1].x+nc.mesh[j].x-nc.mesh[j-1].x,nodes[i][j-1].y+nc.mesh[j].y-nc.mesh[j-1].y,nodes[i][j-1].z+nc.mesh[j].z-nc.mesh[j-1].z){
            public String get_Id(){ return Id+"."+super.get_Id(); }
          };
        }
      }
    }else if(curve2 instanceof _PLine){
      _Node[] nodes_tmp = new _Node[N];
      _PLine ln = (_PLine)curve2;
      int k=0;
      float[] p1,p2;
      for(int i=0; i<ln.nodes.length-1; i++){
        p1 = ln.nodes[i];
        p2 = ln.nodes[i+1];
        float len = (float)Math.sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2]));
        int MM=(int)Math.round(len/msh_size);
        if(MM==0)MM=1;
        float dl = len/MM;
        for(int j=0; j<MM; j++){
          float delta = j*dl/(len-j*dl);
          float x = (p1[0]+delta*p2[0])/(1+delta);
          float y = (p1[1]+delta*p2[1])/(1+delta);
          float z = (p1[2]+delta*p2[2])/(1+delta);
          nodes_tmp[k]=new _Node(x,y,z){
            public String get_Id(){ return Id+"."+super.get_Id(); }
          };
          k++;
        }
      }
      p2 = ln.nodes[0];
      p1 = ln.nodes[ln.nodes.length-1];
      if(ln.close && !(p1[0]==p2[0] && p1[1]==p2[1] && p1[2]==p2[2])){
        float len = (float)Math.sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2]));
        int MM=(int)Math.round(len/msh_size);
        if(MM==0)MM=1;
        float dl = len/MM;
        for(int j=0; j<MM; j++){
          float delta = j*dl/(len-j*dl);
          float x = (p1[0]+delta*p2[0])/(1+delta);
          float y = (p1[1]+delta*p2[1])/(1+delta);
          float z = (p1[2]+delta*p2[2])/(1+delta);
          nodes_tmp[k]=new _Node(x,y,z){
            public String get_Id(){ return Id+"."+super.get_Id(); }
          };
          k++;
        }
        nodes_tmp[N-1]=new _Node(p2[0],p2[1],p2[2]){
          public String get_Id(){ return Id+"."+super.get_Id(); }
        };
      } else {
        p1 = ln.nodes[ln.nodes.length-1];
        nodes_tmp[N-1]=new _Node(p1[0],p1[1],p1[2]){
          public String get_Id(){ return Id+"."+super.get_Id(); }
        };
      }
      for(int i=0; i<M; i++){
        for(int j=1; j<N; j++){
          nodes[i][j]=new _Node(nodes[i][j-1].x+nodes_tmp[j].x-nodes_tmp[j-1].x,nodes[i][j-1].y+nodes_tmp[j].y-nodes_tmp[j-1].y,nodes[i][j-1].z+nodes_tmp[j].z-nodes_tmp[j-1].z){
            public String get_Id(){ return Id+"."+super.get_Id(); }
          };
        }
      }
    }
    /*for(int i=0; i<M; i++){
      for(int j=0; j<N; j++){
        nodes[i][j].set_Id((i*N+j)+"");
      }
    }*/
    if(curve1 instanceof _PLine && ((_PLine)curve1).close) for(int i=0; i<N; i++) nodes[M-1][i]=nodes[0][i];
    if(curve2 instanceof _PLine && ((_PLine)curve2).close) for(int i=0; i<M; i++) nodes[i][N-1]=nodes[i][0];
    for(int i=0; i<nodes.length-1; i++)
      for(int j=0; j<nodes[0].length-1; j++)
        if(msh_type==Canvas3D.MESH_Contact_Triangle || msh_type==Canvas3D.MESH_Shell_C0_3){
           elementsDB.addElement(new _Element3(nodes[i][j],nodes[i][j+1],nodes[i+1][j+1],msh_type,material,thickness){
             public String get_Id(){ return Id+"."+super.get_Id(); }
           });
           elementsDB.addElement(new _Element3(nodes[i][j],nodes[i+1][j+1],nodes[i+1][j],msh_type,material,thickness){
             public String get_Id(){ return Id+"."+super.get_Id(); }
           });
        }else if(msh_type==Canvas3D.MESH_Shell_BT_4){
          elementsDB.addElement(new _Element4(nodes[i][j],nodes[i][j+1],nodes[i+1][j+1],nodes[i+1][j],material,thickness){
            public String get_Id(){ return Id+"."+super.get_Id(); }
          });
        }
    for(int i=0; i<nodes.length; i++)
      for(int j=0; j<nodes[0].length; j++) nodesDB.addElement(nodes[i][j]);
    for(int i=0; i<nodesDB.size(); i++) ((_Object)nodesDB.elementAt(i)).set_Id(i+"");
    for(int i=0; i<elementsDB.size(); i++) ((_Object)elementsDB.elementAt(i)).set_Id(i+"");
  }

  public Object[] get_Array(Canvas3D j3d){
    int ncl=0;
    for(int i=0; i<nodesDB.size(); i++){
      _Node nd = (_Node)nodesDB.elementAt(i);
      if(nd.constraint!=null && j3d.SHOW_ID_CONSTRAINTS)ncl++;
      if(nd.load!=null && j3d.SHOW_ID_LOADS)ncl++;
    }
    if(j3d.SHOW_ID_LOADS){
      for(int i=0; i<elementsDB.size(); i++){
        if(elementsDB.elementAt(i) instanceof _Element3){
          _Element3 el3 = (_Element3)elementsDB.elementAt(i);
          if(el3.load!=null && el3.msh_type==Canvas3D.MESH_Shell_C0_3)ncl++;
        }else if(elementsDB.elementAt(i) instanceof _Element4 && ((_Element4)elementsDB.elementAt(i)).load!=null)ncl++;
      }
    }
    Object[] arr = new Object[nodesDB.size()*(j3d.SHOW_ID_NODE?2:1)+elementsDB.size()*(j3d.SHOW_ID_ELEMENT?2:1)+ncl];
    int k=0;
    for(int i=0; i<nodesDB.size(); i++){
      _Node nd = (_Node)nodesDB.elementAt(i);
      arr[k]= nd.get_Array(j3d)[0];
      k++;
      if(j3d.SHOW_ID_NODE){
        arr[k]=new shpOrientedText(nd.get_Id(),nd.x,nd.y,nd.z);
        k++;
      }
    }
    for(int i=0; i<elementsDB.size(); i++){
      arr[k]=((_Object)elementsDB.elementAt(i)).get_Array(j3d)[0];
      k++;
      if(j3d.SHOW_ID_ELEMENT){
        if(msh_type==j3d.MESH_Shell_BT_4){
          _Element4 el = (_Element4)elementsDB.elementAt(i);
          arr[k]=new shpOrientedText(el.get_Id(),(el.node1.x+el.node2.x+el.node3.x+el.node4.x)/4,(el.node1.y+el.node2.y+el.node3.y+el.node4.y)/4,(el.node1.z+el.node2.z+el.node3.z+el.node4.z)/4);
        }else{
          _Element3 el = (_Element3)elementsDB.elementAt(i);
          arr[k]=new shpOrientedText(el.get_Id(),(el.node1.x+el.node2.x+el.node3.x)/3,(el.node1.y+el.node2.y+el.node3.y)/3,(el.node1.z+el.node2.z+el.node3.z)/3);
        }
        k++;
      }
    }
    for(int i=0; i<nodesDB.size(); i++){
      _Node nd = (_Node)nodesDB.elementAt(i);
      if(nd.constraint!=null && j3d.SHOW_ID_CONSTRAINTS){
        arr[k]=new shpOrientedText(nd.constraint.name,nd.x,nd.y,nd.z,nd.constraint.color);
        k++;
      }
      if(nd.load!=null && j3d.SHOW_ID_LOADS){
        arr[k]=new shpOrientedText(nd.load.name,nd.x,nd.y,nd.z,nd.load.color);
      k++;
      }
    }
    if(j3d.SHOW_ID_LOADS){
      for(int i=0; i<elementsDB.size(); i++){
        if(elementsDB.elementAt(i) instanceof _Element3){
          _Element3 el3 = (_Element3)elementsDB.elementAt(i);
          if(el3.load!=null && el3.msh_type==Canvas3D.MESH_Shell_C0_3){
            arr[k]=new shpOrientedText(el3.load.name,(el3.node1.x+el3.node2.x+el3.node3.x)/3,(el3.node1.y+el3.node2.y+el3.node3.y)/3,(el3.node1.z+el3.node2.z+el3.node3.z)/3,el3.load.color);
            k++;
          }
        }else if(elementsDB.elementAt(i) instanceof _Element4 && ((_Element4)elementsDB.elementAt(i)).load!=null){
          _Element4 el4 = (_Element4)elementsDB.elementAt(i);
          arr[k]=new shpOrientedText(el4.load.name,(el4.node1.x+el4.node2.x+el4.node3.x+el4.node4.x)/4,(el4.node1.y+el4.node2.y+el4.node3.y+el4.node4.y)/4,(el4.node1.z+el4.node2.z+el4.node3.z+el4.node4.z)/4,el4.load.color);
          k++;
        }
      }
    }
    return arr;
  }

  public String get_Id(){ return Id; }
  public void set_Id(String id){ Id=id; }
  public boolean isSelected(){return selected;}

  public void Select(String st){
    selected=st!=null;
    if(st==null){
      for(int i=0; i<nodesDB.size(); i++) ((_Node)nodesDB.elementAt(i)).Select(st);
      for(int i=0; i<elementsDB.size(); i++) ((_Object)elementsDB.elementAt(i)).Select(st);
    }
  }

  public String toString(){ return "SurfDir ID="+Id;}
  public MutableTreeNode get_TreeNode(){
    DefaultMutableTreeNode node = new DefaultMutableTreeNode(this);
    DefaultMutableTreeNode n_nodes = new DefaultMutableTreeNode("Nodes");
    DefaultMutableTreeNode n_elements = new DefaultMutableTreeNode("Elements");
    node.add(curve1.get_TreeNode());
    node.add(curve2.get_TreeNode());
    for(int i=0; i<nodesDB.size(); i++) n_nodes.add(((_Object)nodesDB.elementAt(i)).get_TreeNode());
    node.add(n_nodes);
    for(int i=0; i<elementsDB.size(); i++) n_elements.add(((_Object)elementsDB.elementAt(i)).get_TreeNode());
    node.add(n_elements);
    return node;
  }
  public void transform3D(Matrix3D t){
    for(int i=0; i<nodesDB.size(); i++) ((_Node)nodesDB.elementAt(i)).transform3D(t);
    /*for(int i=0; i<M; i++){
      for(int j=0; j<N; j++){
        nodes[i][j].transform3D(t);
      }
    }*/
  }
  public void error(Object st){
    JOptionPane.showMessageDialog(null,"Error: "+st,"Error!",JOptionPane.ERROR_MESSAGE);
    if(st instanceof Exception) ((Exception)st).printStackTrace(); else System.out.println("Error: "+st);
  }
  public JPanel getEditPanel(Canvas3D j3d, PreProcessor pp){
    J3D=j3d;
    PreP = pp;
    tfcurve1 = new JTextField(curve1+"",3);
    tfcurve2 = new JTextField(curve2+"",3);
    tfsize = new JTextField(msh_size+"",3);
    tft = new JTextField(thickness+"",3);
    String[] type = {"Contact_Triangle","Shell_C0_3","Shell_BT_4"};
    cb_msh_type = new JComboBox(type);
    cb_msh_type.setSelectedItem(msh_name);
    cb_mat = new JComboBox();
    JPanel p = new JPanel(new BorderLayout());
    JPanel p1 = new JPanel(new BorderLayout());
    JPanel p2 = new JPanel(new BorderLayout());
    JPanel p3 = new JPanel(new GridLayout(2,3));
    JPanel p4 = new JPanel(new GridLayout(4,1));
    JPanel p5 = new JPanel(new BorderLayout());
    JPanel p6 = new JPanel(new BorderLayout());
    JPanel p7 = new JPanel(new BorderLayout());
    JPanel p8 = new JPanel(new BorderLayout());
    JButton b_upd = new JButton("Update");
    b_upd.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        try{
        if(curve1==null || curve2==null)return;
        int t=-1;
        if(cb_msh_type.getSelectedIndex()==0)t=Canvas3D.MESH_Contact_Triangle;
        else if(cb_msh_type.getSelectedIndex()==1)t=Canvas3D.MESH_Shell_C0_3;
        else if(cb_msh_type.getSelectedIndex()==2)t=Canvas3D.MESH_Shell_BT_4;
        msh_size=Float.parseFloat(tfsize.getText());
        msh_type=t;
        material=(Material)PreP.MatDB.get(cb_mat.getSelectedItem()+"");
        thickness=Float.parseFloat(tft.getText());
        reset();
        J3D.tree_reset();
        J3D.view_reset();
        }catch(Exception e1) {error(e1);}
      }
    });
    JLabel lb = new JLabel("Edit - "+toString());
    lb.setForeground(Color.blue);
    //jLabel1.setText("Surface on a direction");
    tfcurve2.setEditable(false);
    tfcurve1.setEditable(false);
    JButton b_1 = new JButton("<<");
    b_1.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        Object obj = J3D.getSelectedObject3D();
        if(obj!=null && (obj instanceof _Line || obj instanceof _PLine || obj instanceof _NurbCurve)){
          curve1=(_Object)obj;
          tfcurve1.setText(obj.toString());
        }else{
          curve1=null;
          tfcurve1.setText("");
        }
      }
    });
    JButton b_2 = new JButton("<<");
    b_2.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        Object obj = J3D.getSelectedObject3D();
        if(obj!=null && (obj instanceof _Line || obj instanceof _PLine || obj instanceof _NurbCurve)){
          curve2=(_Object)obj;
          tfcurve2.setText(obj.toString());
        }else{
          curve2=null;
          tfcurve2.setText("");
        }
      }
    });
    p.add(p2,  BorderLayout.SOUTH);
    p2.add(b_upd, null);
    p.add(lb, BorderLayout.NORTH);
    p.add(p1, BorderLayout.CENTER);
    p1.add(p3,  BorderLayout.CENTER);
    p3.add(new JLabel("Curve"), null);
    p3.add(tfcurve1, null);
    p3.add(b_1, null);
    p3.add(new JLabel("Direction"), null);
    p3.add(tfcurve2, null);
    p3.add(b_2, null);
    p1.add(p4,  BorderLayout.SOUTH);
    p4.add(p5, null);
    p5.add(new JLabel("Mesh Size"),  BorderLayout.WEST);
    p5.add(tfsize,  BorderLayout.CENTER);
    p4.add(p6, null);
    p6.add(new JLabel("Mesh Type"),  BorderLayout.WEST);
    p6.add(cb_msh_type,  BorderLayout.CENTER);
    p4.add(p7, null);
    p7.add(new JLabel("Material"), BorderLayout.WEST);
    p7.add(cb_mat, BorderLayout.CENTER);
    p4.add(p8, null);
    p8.add(new JLabel("Thickness"), BorderLayout.WEST);
    p8.add(tft, BorderLayout.CENTER);
    for(Enumeration en = PreP.MatDB.keys(); en.hasMoreElements();)  cb_mat.addItem(en.nextElement());
    cb_mat.setSelectedItem(material.name);
    p.validate();
    return p;
  }
  public _Node[] get_Nodes(){
    _Node[] arr = new _Node[nodesDB.size()];
    for(int i=0; i<nodesDB.size(); i++) arr[i] = (_Node)nodesDB.elementAt(i);
    return arr;
  }
  public _Object[] get_Elements(){
    _Object[] arr = new _Object[elementsDB.size()];
    for(int i=0; i<elementsDB.size(); i++) arr[i] = (_Object)elementsDB.elementAt(i);
    return arr;
  }
}