Ivan Mahonin 911124
Ivan Mahonin 911124
#include <tools/assistant.h>
Ivan Mahonin 911124
Ivan Mahonin 9cf8be
#include <tgl.h>
Ivan Mahonin 3bac66
#include <tproperty.h>
Ivan Mahonin 9cf8be
Ivan Mahonin 911124
#include <limits>
Ivan Mahonin c5e805
#include <cassert>
Ivan Mahonin 911124
Ivan Mahonin e48ced
#ifdef MACOSX
Ivan Mahonin e48ced
const double line_width_scale = 1.5;
Ivan Mahonin e48ced
#else
Ivan Mahonin e48ced
const double line_width_scale = 1.0;
Ivan Mahonin e48ced
#endif
Ivan Mahonin 911124
Ivan Mahonin 911124
//************************************************************************
Ivan Mahonin 911124
//    TGuideline implementation
Ivan Mahonin 911124
//************************************************************************
Ivan Mahonin 911124
Ivan Mahonin 4df9cd
void
Ivan Mahonin 8074a5
TGuideline::drawSegment(
Ivan Mahonin 8074a5
  const TPointD &p0,
Ivan Mahonin 8074a5
  const TPointD &p1,
Ivan Mahonin 8074a5
  double pixelSize,
Ivan Mahonin 8074a5
  bool active,
Ivan Mahonin 8074a5
  bool enabled ) const
Ivan Mahonin 8074a5
{
Ivan Mahonin 4df9cd
  double colorBlack[4] = { 0.0, 0.0, 0.0, 0.5 };
Ivan Mahonin 4df9cd
  double colorWhite[4] = { 1.0, 1.0, 1.0, 0.5 };
Ivan Mahonin 8074a5
Ivan Mahonin 8074a5
  if (!this->enabled || !enabled)
Ivan Mahonin 8074a5
    colorBlack[3] = (colorWhite[3] = 0.25);
Ivan Mahonin 8074a5
  else if (!active)
Ivan Mahonin 8074a5
    colorBlack[3] = (colorWhite[3] = 0.75);
Ivan Mahonin 4df9cd
Ivan Mahonin 4df9cd
  glPushAttrib(GL_ALL_ATTRIB_BITS);
Ivan Mahonin 4df9cd
  tglEnableBlending();
Ivan Mahonin e48ced
  tglEnableLineSmooth(true, 1.0 * line_width_scale);
Ivan Mahonin 4df9cd
  TPointD d = p1 - p0;
Ivan Mahonin 4df9cd
  double k = norm2(d);
Ivan Mahonin 4df9cd
  if (k > TConsts::epsilon*TConsts::epsilon) {
Ivan Mahonin e48ced
    k = 0.5*pixelSize*line_width_scale/sqrt(k);
Ivan Mahonin 4df9cd
    d = TPointD(-k*d.y, k*d.x);
Ivan Mahonin 4df9cd
    glColor4dv(colorWhite);
Ivan Mahonin 4df9cd
    tglDrawSegment(p0 - d, p1 - d);
Ivan Mahonin 4df9cd
    glColor4dv(colorBlack);
Ivan Mahonin 4df9cd
    tglDrawSegment(p0 + d, p1 + d);
Ivan Mahonin 4df9cd
  }
Ivan Mahonin 4df9cd
  glPopAttrib();
Ivan Mahonin 4df9cd
}
Ivan Mahonin 4df9cd
Ivan Mahonin 4df9cd
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 4df9cd
Ivan Mahonin 911124
double
Ivan Mahonin 9cf8be
TGuideline::calcTrackWeight(const TTrack &track, const TAffine &toScreen, bool &outLongEnough) const {
Ivan Mahonin 9cf8be
  outLongEnough = false;
Ivan Mahonin 8074a5
  if (!enabled || track.size() < 2)
Ivan Mahonin 911124
    return std::numeric_limits<double>::infinity();
Ivan Mahonin 911124
Ivan Mahonin 911124
  const double snapLenght = 20.0;
Ivan Mahonin 911124
  const double snapScale = 1.0;
Ivan Mahonin 362052
  const double maxLength = 2.0*snapLenght*snapScale;
Ivan Mahonin 911124
Ivan Mahonin 911124
  double sumWeight = 0.0;
Ivan Mahonin 911124
  double sumLength = 0.0;
Ivan Mahonin 911124
  double sumDeviation = 0.0;
Ivan Mahonin 911124
Ivan Mahonin 9cf8be
  TPointD prev = toScreen*track[0].position;
Ivan Mahonin 911124
  for(int i = 0; i < track.size(); ++i) {
Ivan Mahonin 911124
    const TTrackPoint &tp = track[i];
Ivan Mahonin 9cf8be
    TPointD p = toScreen*tp.position;
Ivan Mahonin 911124
    double length = tdistance(p, prev);
Ivan Mahonin 911124
    sumLength += length;
Ivan Mahonin 911124
Ivan Mahonin 911124
    double midStepLength = sumLength - 0.5*length;
Ivan Mahonin 9f0c16
    if (midStepLength > TConsts::epsilon) {
Ivan Mahonin 911124
      double weight = length*logNormalDistribuitionUnscaled(midStepLength, snapLenght, snapScale);
Ivan Mahonin 911124
      sumWeight += weight;
Ivan Mahonin 911124
Ivan Mahonin 911124
      TTrackPoint ntp = transformPoint(tp);
Ivan Mahonin 9cf8be
      double deviation = tdistance(toScreen*ntp.position, p);
Ivan Mahonin 911124
      sumDeviation += weight*deviation;
Ivan Mahonin 911124
    }
Ivan Mahonin 911124
    prev = p;
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
    if (sumLength >= maxLength)
Ivan Mahonin 9cf8be
      { outLongEnough = true; break; }
Ivan Mahonin 911124
  }
Ivan Mahonin 9f0c16
  return sumWeight > TConsts::epsilon
Ivan Mahonin 9cf8be
       ? sumDeviation/sumWeight
Ivan Mahonin 9cf8be
       : std::numeric_limits<double>::infinity();
Ivan Mahonin 911124
}
Ivan Mahonin 911124
Ivan Mahonin 911124
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 911124
Ivan Mahonin 911124
TGuidelineP
Ivan Mahonin 9cf8be
TGuideline::findBest(const TGuidelineList &guidelines, const TTrack &track, const TAffine &toScreen, bool &outLongEnough) {
Ivan Mahonin 9cf8be
  outLongEnough = true;
Ivan Mahonin 911124
  double bestWeight = 0.0;
Ivan Mahonin 911124
  TGuidelineP best;
Ivan Mahonin 911124
  for(TGuidelineList::const_iterator i = guidelines.begin(); i != guidelines.end(); ++i) {
Ivan Mahonin 9cf8be
    double weight = (*i)->calcTrackWeight(track, toScreen, outLongEnough);
Ivan Mahonin 911124
    if (!best || weight < bestWeight)
Ivan Mahonin 911124
      { bestWeight = weight; best = *i; }
Ivan Mahonin 911124
  }
Ivan Mahonin 911124
  return best;
Ivan Mahonin 911124
}
Ivan Mahonin 911124
Ivan Mahonin 911124
Ivan Mahonin 911124
//************************************************************************
Ivan Mahonin 249386
//    TAssistantPoint implementation
Ivan Mahonin 249386
//************************************************************************
Ivan Mahonin 249386
Ivan Mahonin 7900ea
TAssistantPoint::TAssistantPoint(const TStringId &name, const TPointD &defPosition):
Ivan Mahonin c5e805
  name(name),
Ivan Mahonin 7900ea
  defPosition(defPosition),
Ivan Mahonin c5e805
  type(Circle),
Ivan Mahonin e48ced
  position(defPosition),
Ivan Mahonin 249386
  radius(10.0),
Ivan Mahonin c5e805
  visible(true),
Ivan Mahonin 249386
  selected() { }
Ivan Mahonin 249386
Ivan Mahonin 249386
Ivan Mahonin 249386
//************************************************************************
Ivan Mahonin 4da757
//    TAssistantType implementation
Ivan Mahonin 4da757
//************************************************************************
Ivan Mahonin 4da757
Ivan Mahonin 4da757
TMetaObjectHandler*
Ivan Mahonin 4da757
TAssistantType::createHandler(TMetaObject &obj) const
Ivan Mahonin 4da757
  { return createAssistant(obj); }
Ivan Mahonin 4da757
Ivan Mahonin 4da757
Ivan Mahonin 4da757
//************************************************************************
Ivan Mahonin 911124
//    TAssistant implementation
Ivan Mahonin 911124
//************************************************************************
Ivan Mahonin 911124
Ivan Mahonin 9cf8be
TAssistant::TAssistant(TMetaObject &object):
Ivan Mahonin 9cf8be
  TMetaObjectHandler(object),
Ivan Mahonin 3bac66
  m_idEnabled("enabled"),
Ivan Mahonin 9cf8be
  m_idPoints("points"),
Ivan Mahonin 9cf8be
  m_idX("x"),
Ivan Mahonin 3bac66
  m_idY("y"),
Ivan Mahonin c5e805
  m_idMagnetism("magnetism"),
Ivan Mahonin c5e805
  m_basePoint()
Ivan Mahonin 3bac66
{
Ivan Mahonin 4da757
  addProperty( new TBoolProperty(m_idEnabled.str(), getEnabled()) );
Ivan Mahonin 4da757
  addProperty( new TDoubleProperty(m_idMagnetism.str(), 0.0, 1.0, getMagnetism()) );
Ivan Mahonin 3bac66
}
Ivan Mahonin 3bac66
Ivan Mahonin 3bac66
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 3bac66
Ivan Mahonin c5e805
TAssistantPoint&
Ivan Mahonin c5e805
TAssistant::addPoint(
Ivan Mahonin c5e805
  const TStringId &name,
Ivan Mahonin c5e805
  TAssistantPoint::Type type,
Ivan Mahonin 7900ea
  const TPointD &defPosition,
Ivan Mahonin c5e805
  bool visible,
Ivan Mahonin c5e805
  double radius )
Ivan Mahonin c5e805
{
Ivan Mahonin c5e805
  assert(!m_points.count(name));
Ivan Mahonin c5e805
  TAssistantPoint &p = m_points.insert(
Ivan Mahonin 7900ea
    TAssistantPointMap::value_type(name, TAssistantPoint(name, defPosition)) ).first->second;
Ivan Mahonin 7900ea
  m_pointsOrder.push_back(&p);
Ivan Mahonin c5e805
  p.type     = type;
Ivan Mahonin c5e805
  p.radius   = radius;
Ivan Mahonin c5e805
  p.visible  = visible;
Ivan Mahonin c5e805
  if (!m_basePoint) m_basePoint = &p;
Ivan Mahonin c5e805
  return p;
Ivan Mahonin c5e805
}
Ivan Mahonin c5e805
Ivan Mahonin c5e805
//---------------------------------------------------------------------------------------------------
Ivan Mahonin c5e805
Ivan Mahonin c5e805
TAssistantPoint&
Ivan Mahonin c5e805
TAssistant::addPoint(
Ivan Mahonin c5e805
  const TStringId &name,
Ivan Mahonin c5e805
  TAssistantPoint::Type type,
Ivan Mahonin 7900ea
  const TPointD &defPosition,
Ivan Mahonin c5e805
  bool visible )
Ivan Mahonin 7900ea
    { return addPoint(name, type, defPosition, visible, 10.0); }
Ivan Mahonin c5e805
Ivan Mahonin c5e805
//---------------------------------------------------------------------------------------------------
Ivan Mahonin c5e805
Ivan Mahonin c5e805
const TAssistantPoint&
Ivan Mahonin c5e805
TAssistant::getBasePoint() const
Ivan Mahonin c5e805
  { assert(m_basePoint); return *m_basePoint; }
Ivan Mahonin c5e805
Ivan Mahonin c5e805
//---------------------------------------------------------------------------------------------------
Ivan Mahonin c5e805
Ivan Mahonin 3bac66
void
Ivan Mahonin 4da757
TAssistant::addProperty(TProperty *p)
Ivan Mahonin 4da757
  { m_properties.add(p); }
Ivan Mahonin 4da757
Ivan Mahonin 4da757
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 4da757
Ivan Mahonin 4da757
void
Ivan Mahonin 4da757
TAssistant::setTranslation(const TStringId &name, const QString &localName) const
Ivan Mahonin 4da757
  { m_properties.getProperty(name)->setQStringName( localName ); }
Ivan Mahonin 4da757
Ivan Mahonin 4da757
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 4da757
Ivan Mahonin 4da757
void
Ivan Mahonin 4da757
TAssistant::updateTranslation() const {
Ivan Mahonin 4da757
  setTranslation(m_idEnabled, tr("Enabled"));
Ivan Mahonin 4da757
  setTranslation(m_idMagnetism, tr("Magnetism"));
Ivan Mahonin 3bac66
}
Ivan Mahonin 3bac66
Ivan Mahonin 3bac66
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 3bac66
Ivan Mahonin 3bac66
void
Ivan Mahonin 3bac66
TAssistant::onSetDefaults() {
Ivan Mahonin 3bac66
  setEnabled(true);
Ivan Mahonin 3bac66
  setMagnetism(1.0);
Ivan Mahonin 7900ea
  for(TAssistantPointMap::iterator i = m_points.begin(); i != m_points.end(); ++i)
Ivan Mahonin 7900ea
    i->second.position = i->second.defPosition;
Ivan Mahonin 7900ea
  fixPoints();
Ivan Mahonin 7900ea
  fixData();
Ivan Mahonin 3bac66
}
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 9cf8be
Ivan Mahonin c5e805
void
Ivan Mahonin c5e805
TAssistant::fixPoints()
Ivan Mahonin c5e805
  { onFixPoints(); }
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 9cf8be
Ivan Mahonin b15438
bool
Ivan Mahonin 7900ea
TAssistant::move(const TPointD &position) {
Ivan Mahonin 7900ea
  TPointD d = position - getBasePoint().position;
Ivan Mahonin b15438
  if (d != TPointD()) {
Ivan Mahonin b15438
    for(TAssistantPointMap::iterator i = m_points.begin(); i != m_points.end(); ++i)
Ivan Mahonin b15438
      i->second.position += d;
Ivan Mahonin b15438
    fixPoints();
Ivan Mahonin b15438
    return true;
Ivan Mahonin b15438
  }
Ivan Mahonin b15438
  return false;
Ivan Mahonin 7900ea
}
Ivan Mahonin 7900ea
Ivan Mahonin 7900ea
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 7900ea
Ivan Mahonin b15438
bool
Ivan Mahonin c5e805
TAssistant::movePoint(const TStringId &name, const TPointD &position) {
Ivan Mahonin c5e805
  TAssistantPointMap::iterator i = m_points.find(name);
Ivan Mahonin b15438
  if (i != m_points.end() && i->second.position != position) {
Ivan Mahonin c5e805
    onMovePoint(i->second, position);
Ivan Mahonin b15438
    return true;
Ivan Mahonin b15438
  }
Ivan Mahonin b15438
  return false;
Ivan Mahonin c5e805
}
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
void
Ivan Mahonin c5e805
TAssistant::setPointSelection(const TStringId &name, bool selected)  const {
Ivan Mahonin c5e805
  if (const TAssistantPoint *p = findPoint(name))
Ivan Mahonin c5e805
    p->selected = selected;
Ivan Mahonin c5e805
}
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
void
Ivan Mahonin c5e805
TAssistant::setAllPointsSelection(bool selected) const {
Ivan Mahonin c5e805
  for(TAssistantPointMap::const_iterator i = points().begin(); i != points().end(); ++i)
Ivan Mahonin c5e805
    i->second.selected = selected;
Ivan Mahonin 9cf8be
}
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
void
Ivan Mahonin 9cf8be
TAssistant::onDataChanged(const TVariant &value) {
Ivan Mahonin 9cf8be
  const TVariant& pointsData = data()[m_idPoints];
Ivan Mahonin 9cf8be
  TVariantPathEntry entry;
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
  if (&value == &data() || &value == &pointsData)
Ivan Mahonin 9cf8be
    onAllDataChanged();
Ivan Mahonin 9cf8be
  else
Ivan Mahonin c5e805
  if (pointsData.getChildPathEntry(value, entry) && entry.isField()) {
Ivan Mahonin 9cf8be
    const TVariant& pointData = pointsData[entry];
Ivan Mahonin 9cf8be
    TPointD position = TPointD(
Ivan Mahonin 9cf8be
      pointData[m_idX].getDouble(),
Ivan Mahonin 9cf8be
      pointData[m_idY].getDouble() );
Ivan Mahonin c5e805
    movePoint(entry.field(), position);
Ivan Mahonin 3bac66
  } else
Ivan Mahonin 3bac66
  if (data().getChildPathEntry(value, entry) && entry.isField()) {
Ivan Mahonin 7900ea
    onDataFieldChanged(entry.field(), data()[entry.field()]);
Ivan Mahonin 9cf8be
  }
Ivan Mahonin 9cf8be
}
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
void
Ivan Mahonin 7900ea
TAssistant::onDataFieldChanged(const TStringId &name, const TVariant &value) {
Ivan Mahonin 7900ea
  updateProperty(name, value);
Ivan Mahonin 7900ea
}
Ivan Mahonin 7900ea
Ivan Mahonin 7900ea
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 7900ea
Ivan Mahonin 7900ea
void
Ivan Mahonin 9cf8be
TAssistant::onAllDataChanged() {
Ivan Mahonin 9cf8be
  const TVariant& pointsData = data()[m_idPoints];
Ivan Mahonin c5e805
  for(TAssistantPointMap::iterator i = m_points.begin(); i != m_points.end(); ++i) {
Ivan Mahonin c5e805
    const TVariant& pointData = pointsData[i->first];
Ivan Mahonin c5e805
    i->second.position = TPointD(
Ivan Mahonin 9cf8be
      pointData[m_idX].getDouble(),
Ivan Mahonin 9cf8be
      pointData[m_idY].getDouble() );
Ivan Mahonin 9cf8be
  }
Ivan Mahonin 249386
  fixPoints();
Ivan Mahonin 3bac66
  updateProperties();
Ivan Mahonin 9cf8be
}
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
void
Ivan Mahonin 9cf8be
TAssistant::onFixPoints()
Ivan Mahonin 9cf8be
  { }
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
void
Ivan Mahonin c5e805
TAssistant::onMovePoint(TAssistantPoint &point, const TPointD &position)
Ivan Mahonin c5e805
  { point.position = position; }
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
void
Ivan Mahonin 9cf8be
TAssistant::onFixData() {
Ivan Mahonin 9cf8be
  TVariant& pointsData = data()[m_idPoints];
Ivan Mahonin c5e805
  for(TAssistantPointMap::const_iterator i = points().begin(); i != points().end(); ++i) {
Ivan Mahonin c5e805
    TVariant& pointData = pointsData[i->first];
Ivan Mahonin c5e805
    pointData[m_idX].setDouble( i->second.position.x );
Ivan Mahonin c5e805
    pointData[m_idY].setDouble( i->second.position.y );
Ivan Mahonin 9cf8be
  }
Ivan Mahonin 3bac66
  setMagnetism( std::max(0.0, std::min(1.0, getMagnetism())) );
Ivan Mahonin 3bac66
}
Ivan Mahonin 3bac66
Ivan Mahonin 3bac66
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 3bac66
Ivan Mahonin 3bac66
void
Ivan Mahonin 3bac66
TAssistant::updateProperties() {
Ivan Mahonin 3bac66
  const TVariantMap &map = data().getMap();
Ivan Mahonin 3bac66
  for(TVariantMap::const_iterator i = map.begin(); i != map.end(); ++i)
Ivan Mahonin 3bac66
    if (i->first != m_idPoints)
Ivan Mahonin 3bac66
      updateProperty(i->first, i->second);
Ivan Mahonin 3bac66
}
Ivan Mahonin 3bac66
Ivan Mahonin 3bac66
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 3bac66
Ivan Mahonin 3bac66
void
Ivan Mahonin 3bac66
TAssistant::updateProperty(const TStringId &name, const TVariant &value) {
Ivan Mahonin 3bac66
  TProperty *property = m_properties.getProperty(name);
Ivan Mahonin 3bac66
  if (!property)
Ivan Mahonin 3bac66
    return;
Ivan Mahonin 3bac66
Ivan Mahonin 3bac66
  if (TBoolProperty *boolProperty = dynamic_cast<TBoolProperty*>(property)) {
Ivan Mahonin 3bac66
    boolProperty->setValue( value.getBool() );
Ivan Mahonin 3bac66
  } else
Ivan Mahonin 3bac66
  if (TDoubleProperty *doubleProperty = dynamic_cast<TDoubleProperty*>(property)) {
Ivan Mahonin 3bac66
    doubleProperty->setValue( value.getDouble() );
Ivan Mahonin 3bac66
  } else
Ivan Mahonin 3bac66
  if (TStringProperty *stringProperty = dynamic_cast<TStringProperty*>(property)) {
Ivan Mahonin 3bac66
    stringProperty->setValue( to_wstring(value.getString()) );
Ivan Mahonin 3bac66
  } else
Ivan Mahonin 3bac66
  if (TEnumProperty *enumProperty = dynamic_cast<TEnumProperty*>(property)) {
Ivan Mahonin 3bac66
    enumProperty->setValue( to_wstring(value.getString()) );
Ivan Mahonin 3bac66
  }
Ivan Mahonin 3bac66
}
Ivan Mahonin 3bac66
Ivan Mahonin 3bac66
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 3bac66
Ivan Mahonin 3bac66
void
Ivan Mahonin 3bac66
TAssistant::onPropertyChanged(const TStringId &name) {
Ivan Mahonin 3bac66
  TProperty *property = m_properties.getProperty(name);
Ivan Mahonin 3bac66
  if (!property)
Ivan Mahonin 3bac66
    return;
Ivan Mahonin 3bac66
Ivan Mahonin 3bac66
  if (name == m_idPoints)
Ivan Mahonin 3bac66
    return;
Ivan Mahonin 3bac66
Ivan Mahonin 3bac66
  if (TBoolProperty *boolProperty = dynamic_cast<TBoolProperty*>(property)) {
Ivan Mahonin 3bac66
    data()[name].setBool( boolProperty->getValue() );
Ivan Mahonin 3bac66
  } else
Ivan Mahonin 3bac66
  if (TDoubleProperty *doubleProperty = dynamic_cast<TDoubleProperty*>(property)) {
Ivan Mahonin 3bac66
    data()[name].setDouble( doubleProperty->getValue() );
Ivan Mahonin 3bac66
  } else
Ivan Mahonin 3bac66
  if (TStringProperty *stringProperty = dynamic_cast<TStringProperty*>(property)) {
Ivan Mahonin 3bac66
    data()[name].setString( to_string(stringProperty->getValue()) );
Ivan Mahonin 3bac66
  } else
Ivan Mahonin 3bac66
  if (TEnumProperty *enumProperty = dynamic_cast<TEnumProperty*>(property)) {
Ivan Mahonin 3bac66
    data()[name].setString( to_string(enumProperty->getValue()) );
Ivan Mahonin 3bac66
  }
Ivan Mahonin 9cf8be
}
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 9cf8be
Ivan Mahonin c7854d
double
Ivan Mahonin c7854d
TAssistant::getDrawingAlpha(bool enabled) const
Ivan Mahonin c7854d
  { return enabled && this->getEnabled() ? 0.5 : 0.25; }
Ivan Mahonin c7854d
Ivan Mahonin c7854d
//---------------------------------------------------------------------------------------------------
Ivan Mahonin c7854d
Ivan Mahonin c7854d
double
Ivan Mahonin c7854d
TAssistant::getDrawingGridAlpha() const
Ivan Mahonin c7854d
  { return 0.2; }
Ivan Mahonin c7854d
Ivan Mahonin c7854d
//---------------------------------------------------------------------------------------------------
Ivan Mahonin c7854d
Ivan Mahonin 9cf8be
void
Ivan Mahonin c7854d
TAssistant::drawSegment(const TPointD &p0, const TPointD &p1, double pixelSize, double alpha) const {
Ivan Mahonin c7854d
  double colorBlack[4] = { 0.0, 0.0, 0.0, alpha };
Ivan Mahonin c7854d
  double colorWhite[4] = { 1.0, 1.0, 1.0, alpha };
Ivan Mahonin 4df9cd
Ivan Mahonin 4df9cd
  glPushAttrib(GL_ALL_ATTRIB_BITS);
Ivan Mahonin 4df9cd
  tglEnableBlending();
Ivan Mahonin e48ced
  tglEnableLineSmooth(true, 1.0 * line_width_scale);
Ivan Mahonin 4df9cd
  TPointD d = p1 - p0;
Ivan Mahonin 4df9cd
  double k = norm2(d);
Ivan Mahonin 4df9cd
  if (k > TConsts::epsilon*TConsts::epsilon) {
Ivan Mahonin e48ced
    k = 0.5*pixelSize*line_width_scale/sqrt(k);
Ivan Mahonin 4df9cd
    d = TPointD(-k*d.y, k*d.x);
Ivan Mahonin 4df9cd
    glColor4dv(colorWhite);
Ivan Mahonin 4df9cd
    tglDrawSegment(p0 - d, p1 - d);
Ivan Mahonin 4df9cd
    glColor4dv(colorBlack);
Ivan Mahonin 4df9cd
    tglDrawSegment(p0 + d, p1 + d);
Ivan Mahonin 4df9cd
  }
Ivan Mahonin 4df9cd
  glPopAttrib();
Ivan Mahonin 4df9cd
}
Ivan Mahonin 4df9cd
Ivan Mahonin 4df9cd
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 4df9cd
Ivan Mahonin 4df9cd
void
Ivan Mahonin c7854d
TAssistant::drawDot(const TPointD &p, double alpha) const {
Ivan Mahonin c7854d
  double colorBlack[4] = { 0.0, 0.0, 0.0, alpha };
Ivan Mahonin c7854d
  double colorWhite[4] = { 1.0, 1.0, 1.0, alpha };
Ivan Mahonin 7900ea
Ivan Mahonin 7900ea
  glPushAttrib(GL_ALL_ATTRIB_BITS);
Ivan Mahonin 7900ea
  tglEnableBlending();
Ivan Mahonin 7900ea
Ivan Mahonin 7900ea
  glColor4dv(colorWhite);
Ivan Mahonin 7c7225
  tglEnablePointSmooth(6.0);
Ivan Mahonin 7900ea
  glBegin(GL_POINTS);
Ivan Mahonin 7900ea
  glVertex2d(p.x, p.y);
Ivan Mahonin 7900ea
  glEnd();
Ivan Mahonin 7900ea
Ivan Mahonin 7900ea
  glColor4dv(colorBlack);
Ivan Mahonin 7c7225
  tglEnablePointSmooth(3.0);
Ivan Mahonin 7900ea
  glBegin(GL_POINTS);
Ivan Mahonin 7900ea
  glVertex2d(p.x, p.y);
Ivan Mahonin 7900ea
  glEnd();
Ivan Mahonin 7900ea
Ivan Mahonin 7900ea
  glPopAttrib();
Ivan Mahonin 7900ea
}
Ivan Mahonin 7900ea
Ivan Mahonin 7900ea
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 7900ea
Ivan Mahonin 7900ea
void
Ivan Mahonin 9cf8be
TAssistant::drawPoint(const TAssistantPoint &point, double pixelSize) const {
Ivan Mahonin c5e805
  if (!point.visible) return;
Ivan Mahonin c5e805
Ivan Mahonin 249386
  double radius = point.radius;
Ivan Mahonin 9cf8be
  double crossSize = 1.2*radius;
Ivan Mahonin 9cf8be
Ivan Mahonin c7854d
  double alpha = 0.5;
Ivan Mahonin c7854d
  double colorBlack[4] = { 0.0, 0.0, 0.0, alpha };
Ivan Mahonin c7854d
  double colorGray[4]  = { 0.5, 0.5, 0.5, alpha };
Ivan Mahonin c7854d
  double colorWhite[4] = { 1.0, 1.0, 1.0, alpha };
Ivan Mahonin e48ced
  double width = 1.5;
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
  if (point.selected) {
Ivan Mahonin 9cf8be
    colorBlack[2] = 1.0;
Ivan Mahonin 9cf8be
    colorGray[2] = 1.0;
Ivan Mahonin 249386
    width = 2.0;
Ivan Mahonin 9cf8be
  }
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
  glPushAttrib(GL_ALL_ATTRIB_BITS);
Ivan Mahonin 9cf8be
Ivan Mahonin 249386
  // fill
Ivan Mahonin 9cf8be
  tglEnableBlending();
Ivan Mahonin 9cf8be
  if (point.type == TAssistantPoint::CircleFill) {
Ivan Mahonin 9cf8be
    glColor4dv(colorGray);
Ivan Mahonin 9cf8be
    tglDrawDisk(point.position, radius*pixelSize);
Ivan Mahonin 9cf8be
  }
Ivan Mahonin 9cf8be
Ivan Mahonin 249386
  TPointD crossDx(pixelSize*crossSize, 0.0);
Ivan Mahonin 249386
  TPointD crossDy(0.0, pixelSize*crossSize);
Ivan Mahonin c7854d
  TPointD gridDx(pixelSize*radius, 0.0);
Ivan Mahonin c7854d
  TPointD gridDy(0.0, pixelSize*radius);
Ivan Mahonin 9cf8be
Ivan Mahonin 249386
  // back line
Ivan Mahonin e48ced
  tglEnableLineSmooth(true, 2.0*width*line_width_scale);
Ivan Mahonin 249386
  glColor4dv(colorWhite);
Ivan Mahonin 249386
  if (point.type == TAssistantPoint::CircleCross) {
Ivan Mahonin 249386
    tglDrawSegment(point.position - crossDx, point.position + crossDx);
Ivan Mahonin 249386
    tglDrawSegment(point.position - crossDy, point.position + crossDy);
Ivan Mahonin e48ced
  }
Ivan Mahonin 249386
  tglDrawCircle(point.position, radius*pixelSize);
Ivan Mahonin 9cf8be
Ivan Mahonin 249386
  // front line
Ivan Mahonin e48ced
  glLineWidth(width * line_width_scale);
Ivan Mahonin 9cf8be
  glColor4dv(colorBlack);
Ivan Mahonin 249386
  if (point.type == TAssistantPoint::CircleCross) {
Ivan Mahonin 249386
    tglDrawSegment(point.position - crossDx, point.position + crossDx);
Ivan Mahonin 249386
    tglDrawSegment(point.position - crossDy, point.position + crossDy);
Ivan Mahonin 249386
  }
Ivan Mahonin 249386
  tglDrawCircle(point.position, radius*pixelSize);
Ivan Mahonin 9cf8be
Ivan Mahonin c7854d
  // dots
Ivan Mahonin c7854d
  switch(point.type) {
Ivan Mahonin c7854d
  case TAssistantPoint::CircleDoubleDots:
Ivan Mahonin c7854d
    drawDot(point.position - gridDx*0.5, alpha);
Ivan Mahonin c7854d
    drawDot(point.position + gridDx*0.5, alpha);
Ivan Mahonin c7854d
    drawDot(point.position - gridDy*0.5, alpha);
Ivan Mahonin c7854d
    drawDot(point.position + gridDy*0.5, alpha);
Ivan Mahonin c7854d
    //no break
Ivan Mahonin c7854d
  case TAssistantPoint::CircleDots:
Ivan Mahonin c7854d
    drawDot(point.position - gridDx, alpha);
Ivan Mahonin c7854d
    drawDot(point.position + gridDx, alpha);
Ivan Mahonin c7854d
    drawDot(point.position - gridDy, alpha);
Ivan Mahonin c7854d
    drawDot(point.position + gridDy, alpha);
Ivan Mahonin c7854d
    //no break
Ivan Mahonin c7854d
  case TAssistantPoint::Circle:
Ivan Mahonin c7854d
    drawDot(point.position, alpha);
Ivan Mahonin c7854d
    break;
Ivan Mahonin c7854d
  default:
Ivan Mahonin c7854d
    break;
Ivan Mahonin c7854d
  }
Ivan Mahonin c7854d
Ivan Mahonin 9cf8be
  glPopAttrib();
Ivan Mahonin 9cf8be
}
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
void
Ivan Mahonin 9cf8be
TAssistant::getGuidelines(const TPointD &position, const TAffine &toTool, TGuidelineList &outGuidelines) const
Ivan Mahonin 9cf8be
  { }
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
void
Ivan Mahonin 8074a5
TAssistant::draw(TToolViewer *viewer, bool enabled) const
Ivan Mahonin 9cf8be
  { }
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
void
Ivan Mahonin 9cf8be
TAssistant::drawEdit(TToolViewer *viewer) const {
Ivan Mahonin 9cf8be
  // paint all points
Ivan Mahonin 4df9cd
  draw(viewer);
Ivan Mahonin 9cf8be
  double pixelSize = sqrt(tglGetPixelSize2());
Ivan Mahonin c5e805
  for(TAssistantPointMap::const_iterator i = points().begin(); i != points().end(); ++i)
Ivan Mahonin c5e805
    drawPoint(i->second, pixelSize);
Ivan Mahonin 9cf8be
}
Ivan Mahonin 9cf8be
Ivan Mahonin 9cf8be
//---------------------------------------------------------------------------------------------------
Ivan Mahonin 9a49d4
Ivan Mahonin 9a49d4
bool
Ivan Mahonin 9a49d4
TAssistant::calcPerspectiveStep(
Ivan Mahonin 9a49d4
  double minStep,
Ivan Mahonin 9a49d4
  double minX,
Ivan Mahonin 9a49d4
  double maxX,
Ivan Mahonin 9a49d4
  double x0,
Ivan Mahonin 9a49d4
  double x1,
Ivan Mahonin 9a49d4
  double x2,
Ivan Mahonin 9a49d4
  double &outK,
Ivan Mahonin 9a49d4
  double &outMin,
Ivan Mahonin 9a49d4
  double &outMax )
Ivan Mahonin 9a49d4
{
Ivan Mahonin 9a49d4
  outK = outMin = outMax = 0.0;
Ivan Mahonin 9a49d4
Ivan Mahonin 9a49d4
  double dx1 = x1 - x0;
Ivan Mahonin 9a49d4
  double dx2 = x2 - x0;
Ivan Mahonin 9a49d4
  if (fabs(dx1) <= TConsts::epsilon) return false;
Ivan Mahonin 9a49d4
  if (fabs(dx2) <= TConsts::epsilon) return false;
Ivan Mahonin 9a49d4
  if ((dx1 < 0.0) != (dx2 < 0.0)) dx2 = -dx2;
Ivan Mahonin 9a49d4
  if (fabs(dx2 - dx1) <= minStep) return false;
Ivan Mahonin 9a49d4
  if (fabs(dx2) < fabs(dx1)) std::swap(dx1, dx2);
Ivan Mahonin 9a49d4
Ivan Mahonin 9a49d4
  if (x0 <= minX + TConsts::epsilon && dx1 < 0.0) return false;
Ivan Mahonin 9a49d4
  if (x0 >= maxX - TConsts::epsilon && dx1 > 0.0) return false;
Ivan Mahonin 9a49d4
Ivan Mahonin 9a49d4
  outK = dx2/dx1;
Ivan Mahonin 9a49d4
  double minI = log(minStep/fabs(dx1*(1.0 - 1.0/outK)))/log(outK);
Ivan Mahonin 9a49d4
  outMin = dx1*pow(outK, floor(minI - TConsts::epsilon));
Ivan Mahonin 9a49d4
  if (fabs(outMin) < TConsts::epsilon) return false;
Ivan Mahonin 9a49d4
  outMax = (dx1 > 0.0 ? maxX : minX) - x0;
Ivan Mahonin 9a49d4
  return true;
Ivan Mahonin 9a49d4
}