text: // Sphere.cpp
  // Copyright (c) 2009, Dan Heeks
  // This program is released under the BSD license. See the file COPYING for details.
  
  #include "stdafx.h"
  #include "Sphere.h"
  #include "../interface/PropertyVertex.h"
  #include "../interface/PropertyDouble.h"
  #include "../interface/PropertyLength.h"
  #include "Gripper.h"
  #include "MarkedList.h"
  
  CSphere::CSphere(const gp_Pnt& pos, double radius, const wxChar* title, const HeeksColor& col, float opacity):CSolid(BRepPrimAPI_MakeSphere(pos, radius), title, col, opacity), m_pos(pos), m_radius(radius)
  {
  }
  
  CSphere::CSphere(const TopoDS_Solid &solid, const wxChar* title, const HeeksColor& col, float opacity):CSolid(solid, title, col, opacity), m_pos(0, 0, 0), m_radius(0.0)
  {
  }
  
  CSphere::CSphere( const CSphere & rhs ) : CSolid(rhs)
  {
      m_pos = rhs.m_pos;
      m_radius = rhs.m_radius;
  }
  
  CSphere & CSphere::operator= ( const CSphere & rhs )
  {
      if (this != &rhs)
      {
          m_pos = rhs.m_pos;
          m_radius = rhs.m_radius;
  
          CSolid::operator=( rhs );
      }
  
      return(*this);
  }
  
  HeeksObj *CSphere::MakeACopy(void)const
  {
  	return new CSphere(*this);
  }
  
  const wxBitmap &CSphere::GetIcon()
  {
  	static wxBitmap* icon = NULL;
  	if(icon == NULL)icon = new wxBitmap(wxImage(wxGetApp().GetResFolder() + _T("/icons/sphere.png")));
  	return *icon;
  }
  
  bool CSphere::IsDifferent(HeeksObj *other)
  {
  	CSphere* sphere = (CSphere*)other;
  	if(sphere->m_pos.Distance(m_pos) > wxGetApp().m_geom_tol || sphere->m_radius != m_radius)
  		return true;
  	return CShape::IsDifferent(other);
  }
  
  static void on_set_centre(const double *pos, HeeksObj* object){
  	((CSphere*)object)->m_pos = make_point(pos);
  	object->OnApplyProperties();
  }
  
  static void on_set_radius(double value, HeeksObj* object){
  	((CSphere*)object)->m_radius = value;
  	object->OnApplyProperties();
  }
  
  void CSphere::MakeTransformedShape(const gp_Trsf &mat)
  {
  	m_pos.Transform(mat);
  	double scale = gp_Vec(1, 0, 0).Transformed(mat).Magnitude();
  	m_radius = fabs(m_radius * scale);
  	m_shape = BRepPrimAPI_MakeSphere(m_pos, m_radius).Shape();
  }
  
  wxString CSphere::StretchedName(){ return _("Ellipsoid");}
  
  void CSphere::GetProperties(std::list<Property *> *list)
  {
  	double pos[3];
  	extract(m_pos, pos);
  	list->push_back(new PropertyVertex(_("centre"), pos, this, on_set_centre));
  	list->push_back(new PropertyLength(_("radius"), m_radius, this, on_set_radius));
  
  	CSolid::GetProperties(list);
  }
  
  void CSphere::GetGripperPositions(std::list<GripData> *list, bool just_for_endof)
  {
  	list->push_back(GripData(GripperTypeTranslate,m_pos.X(),m_pos.Y(),m_pos.Z(),NULL));
  	list->push_back(GripData(GripperTypeScale,m_pos.X() + m_radius,m_pos.Y(),m_pos.Z(),NULL));
  }
  
  void CSphere::OnApplyProperties()
  {
  	*this = CSphere(m_pos, m_radius, m_title.c_str(), m_color, m_opacity);
  	this->create_faces_and_edges();
  	wxGetApp().Repaint();
  }
  
  bool CSphere::GetCentrePoint(double* pos)
  {
  	extract(m_pos, pos);
  	return true;
  }
  
  bool CSphere::GetScaleAboutMatrix(double *m)
  {
  	gp_Trsf mat;
  	mat.SetTranslationPart(gp_Vec(m_pos.XYZ()));
  	extract(mat, m);
  	return true;
  }
  
  void CSphere::SetXMLElement(TiXmlElement* element)
  {
  	element->SetDoubleAttribute("px", m_pos.X());
  	element->SetDoubleAttribute("py", m_pos.Y());
  	element->SetDoubleAttribute("pz", m_pos.Z());
  	element->SetDoubleAttribute("r", m_radius);
  
  	CSolid::SetXMLElement(element);
  }
  
  void CSphere::SetFromXMLElement(TiXmlElement* pElem)
  {
  	// get the attributes
  	for(TiXmlAttribute* a = pElem->FirstAttribute(); a; a = a->Next())
  	{
  		std::string name(a->Name());
  		if(name == "px"){m_pos.SetX(a->DoubleValue());}
  		else if(name == "py"){m_pos.SetY(a->DoubleValue());}
  		else if(name == "pz"){m_pos.SetZ(a->DoubleValue());}
  		else if(name == "r"){m_radius = a->DoubleValue();}
  	}
  
  	CSolid::SetFromXMLElement(pElem);
  }
  