Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 2 // See the file tools.license for terms. 3 4 #ifndef tools_sg_ellipse 5 #define tools_sg_ellipse 6 7 // same logic as ROOT/TEllipse. 8 9 #include "node" 10 #include "sf" 11 #include "render_action" 12 #include "pick_action" 13 #include "bbox_action" 14 15 #include "../mathf" 16 #include "../curve" 17 18 namespace tools { 19 namespace sg { 20 21 class ellipse : public node,public curve { 22 TOOLS_NODE_NO_CAST(ellipse,tools::sg::ellips 23 public: 24 virtual void* cast(const std::string& a_clas 25 if(void* p = cmp_cast<ellipse>(this,a_clas 26 if(void* p = cmp_cast<curve>(this,a_class) 27 return node::cast(a_class); 28 } 29 public: 30 sf<float> rx; 31 sf<float> ry; 32 sf<float> phi_min; //radians 33 sf<float> phi_max; //radians 34 sf<unsigned int> steps; 35 public: 36 virtual const desc_fields& node_desc_fields( 37 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::ell 38 static const desc_fields s_v(parent::node_ 39 TOOLS_ARG_FIELD_DESC(rx), 40 TOOLS_ARG_FIELD_DESC(ry), 41 TOOLS_ARG_FIELD_DESC(phi_min), 42 TOOLS_ARG_FIELD_DESC(phi_max), 43 TOOLS_ARG_FIELD_DESC(steps) 44 ); 45 return s_v; 46 } 47 private: 48 void add_fields(){ 49 add_field(&rx); 50 add_field(&ry); 51 add_field(&phi_min); 52 add_field(&phi_max); 53 add_field(&steps); 54 } 55 public: //curve 56 virtual bool pos_tan_nor(float /*a_s*/, 57 vec3f& a_pos, 58 vec3f& a_tan, 59 vec3f& a_nor) const 60 61 //float r = radius.value(); 62 //float cs = fcos(a_s); 63 //float sn = fsin(a_s); 64 65 float x,y,z; 66 67 {//x = r*cs;y = r*sn;z = 0; 68 x = 0;y = 0;z = 0; 69 m_model.mul_3f(x,y,z); 70 a_pos.set_value(x,y,z);} 71 72 {//x = -sn;y = cs;z = 0; 73 x = 0;y = 1;z = 0; 74 m_model.mul_dir_3(x,y,z); 75 a_tan.set_value(x,y,z);} 76 77 {x = 0;y = 0;z = 1; 78 m_model.mul_dir_3(x,y,z); 79 a_nor.set_value(x,y,z);} 80 81 return true; 82 } 83 public: 84 virtual void copy(curve*& a_new) const {a_ne 85 public: 86 virtual void render(render_action& a_action) 87 if(touched()) { 88 update_sg(); 89 reset_touched(); 90 } 91 //Same logic as Inventor SoLightModel.mode 92 const state& state = a_action.state(); 93 a_action.set_lighting(false); 94 a_action.add_line_strip(m_xyzs); 95 a_action.set_lighting(state.m_GL_LIGHTING) 96 } 97 98 virtual void pick(pick_action& a_action) { 99 if(touched()) { 100 update_sg(); 101 reset_touched(); 102 } 103 if(a_action.stop_at_first()){ 104 a_action.add_line_strip(m_xyzs); 105 if(a_action.done()) a_action.set_node(th 106 } else { 107 a_action.set_done(false); 108 a_action.zs().clear(); 109 a_action.ws().clear(); 110 a_action.add_line_strip(m_xyzs); 111 if(a_action.done()) { 112 a_action.add_pick(*this,a_action.zs(), 113 a_action.set_done(false); 114 } 115 } 116 } 117 virtual void bbox(bbox_action& a_action) { 118 if(touched()) { 119 update_sg(); 120 reset_touched(); 121 } 122 a_action.add_line_strip(m_xyzs); 123 } 124 public: 125 ellipse() 126 :parent() 127 ,curve() 128 ,rx(1) 129 ,ry(1) 130 ,phi_min(0) 131 ,phi_max(tools::ftwo_pi()) 132 ,steps(40) 133 { 134 add_fields(); 135 } 136 virtual ~ellipse(){} 137 public: 138 ellipse(const ellipse& a_from) 139 :parent(a_from) 140 ,curve(a_from) 141 ,rx(a_from.rx) 142 ,ry(a_from.ry) 143 ,phi_min(a_from.phi_min) 144 ,phi_max(a_from.phi_max) 145 ,steps(a_from.steps) 146 { 147 add_fields(); 148 } 149 ellipse& operator=(const ellipse& a_from){ 150 parent::operator=(a_from); 151 curve::operator=(a_from); 152 rx = a_from.rx; 153 ry = a_from.ry; 154 phi_min = a_from.phi_min; 155 phi_max = a_from.phi_max; 156 steps = a_from.steps; 157 return *this; 158 } 159 protected: 160 void update_sg() { 161 m_xyzs.clear(); 162 if(!steps.value()) return; 163 164 unsigned int num = steps.value(); 165 166 //set number of points approximatively prop 167 //float circ = kPI*(r1+r2)*(phi2-phi1)/360; 168 //Int_t n = (Int_t)(np*circ/((gPad->GetX2() 169 //if (n < 8) n= 8; 170 //if (n > np) n = np; 171 172 m_xyzs.resize((num+1)*3); 173 174 float phimin = phi_min.value(); 175 float phimax = phi_max.value(); 176 float r1 = rx.value(); 177 float r2 = ry.value(); 178 179 float phi1 = mn<float>(phimin,phimax); 180 float phi2 = mx<float>(phimin,phimax); 181 182 float angle,dx,dy; 183 float dphi = (phi2-phi1)/float(num); 184 size_t pos = 0; 185 for(unsigned int i=0;i<=num;i++) { 186 angle = phi1 + float(i)*dphi; 187 dx = r1*fcos(angle); 188 dy = r2*fsin(angle); 189 m_xyzs[pos] = dx;pos++; 190 m_xyzs[pos] = dy;pos++; 191 m_xyzs[pos] = 0;pos++; 192 } 193 /* 194 TString opt = option; 195 opt.ToLower(); 196 if (phi2-phi1 >= 360 ) { 197 if (GetFillStyle()) gPad->PaintFillArea( 198 if (GetLineStyle()) gPad->PaintPolyLine( 199 } else { 200 x[n+1] = gPad->XtoPad(x1); 201 y[n+1] = gPad->YtoPad(y1); 202 x[n+2] = x[0]; 203 y[n+2] = y[0]; 204 if (GetFillStyle()) gPad->PaintFillArea( 205 if (GetLineStyle()) { 206 if (TestBit(kNoEdges) || opt.Contains 207 else 208 } 209 } 210 */ 211 212 } 213 214 protected: 215 std::vector<float> m_xyzs; 216 }; 217 218 }} 219 220 #endif