Ejemplo n.º 1
0
void ControlPointEditorStroke::setLinearSpeedIn(int index, bool linear,
                                                bool updatePoints) {
  TStroke *stroke = getStroke();
  if (!stroke || m_controlPoints.size() == 1) return;
  int pointIndex = m_controlPoints[index].m_pointIndex;
  if (pointIndex == 0) {
    if (isSelfLoop())
      pointIndex = stroke->getControlPointCount() - 1;
    else
      return;
  }
  int precIndex =
      (index == 0 && isSelfLoop()) ? m_controlPoints.size() - 1 : index - 1;

  TThickPoint point     = stroke->getControlPoint(pointIndex);
  TThickPoint precPoint = (pointIndex > 2)
                              ? stroke->getControlPoint(pointIndex - 3)
                              : TThickPoint();

  if (linear) {
    TThickPoint p(point - precPoint);
    double n = norm(p);
    TThickPoint speedIn =
        (n != 0.0) ? (0.01 / n) * p : TThickPoint(0.001, 0.001, 0.0);
    m_controlPoints[index].m_speedIn = speedIn;
  } else {
    TThickPoint newPrec2             = (precPoint + point) * 0.5;
    TThickPoint speedIn              = (point - newPrec2) * 0.5;
    m_controlPoints[index].m_speedIn = speedIn;
  }
  if (updatePoints) updateDependentPoint(index);
}
Ejemplo n.º 2
0
void ControlPointEditorStroke::setLinearSpeedOut(int index, bool linear,
                                                 bool updatePoints) {
  TStroke *stroke = getStroke();
  if (!stroke || m_controlPoints.size() == 1) return;
  int cpCount    = stroke->getControlPointCount();
  int pointIndex = m_controlPoints[index].m_pointIndex;
  if (pointIndex == cpCount - 1) {
    if (isSelfLoop())
      pointIndex = 0;
    else
      return;
  }
  int nextIndex =
      (index == m_controlPoints.size() - 1 && isSelfLoop()) ? 0 : index + 1;

  TThickPoint point     = stroke->getControlPoint(pointIndex);
  TThickPoint nextPoint = (pointIndex < cpCount - 3)
                              ? stroke->getControlPoint(pointIndex + 3)
                              : TThickPoint();

  if (linear) {
    TThickPoint p(nextPoint - point);
    double n = norm(p);
    TThickPoint speedOut =
        (n != 0.0) ? (0.01 / n) * p : TThickPoint(0.001, 0.001, 0.0);
    m_controlPoints[index].m_speedOut = speedOut;
  } else {
    TThickPoint newNext2              = (nextPoint + point) * 0.5;
    TThickPoint speedOut              = (newNext2 - point) * 0.5;
    m_controlPoints[index].m_speedOut = speedOut;
  }
  if (updatePoints) updateDependentPoint(index);
}
Ejemplo n.º 3
0
void ControlPointEditorStroke::moveSegment(int beforeIndex, int nextIndex,
                                           const TPointD &delta,
                                           const TPointD &pos) {
  TStroke *stroke = getStroke();
  if (!stroke) return;

  int cpCount = getControlPointCount();
  // Verifiche per il caso in cui lo stroke e' selfLoop
  if (isSelfLoop() && beforeIndex == 0 && nextIndex == cpCount - 1)
    std::swap(beforeIndex, nextIndex);

  int beforePointIndex = m_controlPoints[beforeIndex].m_pointIndex;
  int nextPointIndex   = (isSelfLoop() && nextIndex == 0)
                           ? stroke->getControlPointCount() - 1
                           : m_controlPoints[nextIndex].m_pointIndex;
  double w  = stroke->getW(pos);
  double w0 = stroke->getParameterAtControlPoint(beforePointIndex);
  double w4 = stroke->getParameterAtControlPoint(nextPointIndex);
  if (w0 > w) return;
  assert(w0 <= w && w <= w4);

  double t = 1;
  double s = 1;

  if (isSpeedOutLinear(beforeIndex)) {
    m_controlPoints[beforeIndex].m_speedOut =
        (stroke->getControlPoint(nextPointIndex) -
         stroke->getControlPoint(beforePointIndex)) *
        0.3;
    if (!isSpeedInLinear(beforeIndex))
      m_controlPoints[beforeIndex].m_isCusp = true;
  } else if (!isSpeedOutLinear(beforeIndex) && !isSpeedInLinear(beforeIndex) &&
             !isCusp(beforeIndex)) {
    t = 1 - fabs(w - w0) / fabs(w4 - w0);
    moveSingleControlPoint(beforeIndex, t * delta);
    t = 1 - t;
  }

  if (isSpeedInLinear(nextIndex)) {
    m_controlPoints[nextIndex].m_speedIn =
        (stroke->getControlPoint(nextPointIndex) -
         stroke->getControlPoint(beforePointIndex)) *
        0.3;
    if (!isSpeedOutLinear(nextIndex))
      m_controlPoints[nextIndex].m_isCusp = true;
  } else if (!isSpeedInLinear(nextIndex) && !isSpeedOutLinear(nextIndex) &&
             !isCusp(nextIndex)) {
    s = 1 - fabs(w4 - w) / fabs(w4 - w0);
    moveSingleControlPoint(nextIndex, s * delta);
    s = 1 - s;
  }

  moveSpeedOut(beforeIndex, delta * s, 0);
  // updateDependentPoint(beforeIndex);
  moveSpeedIn(nextIndex, delta * t, 0);
  // updateDependentPoint(nextIndex);

  updatePoints();
}
Ejemplo n.º 4
0
TThickPoint TStrokeBenderDeformation::getDisplacementForControlPoint(
    const TStroke &s, UINT n) const {
  // potenziale exp^(-x^2) limitato tra
  // [-c_maxLenghtOfGaussian,c_maxLenghtOfGaussian]
  double strokeLengthAtParameter = s.getLengthAtControlPoint(n);
  double diff                    = strokeLengthAtParameter - m_startLength;

  if (m_vect) {
    double outVal = 0;

    if (fabs(diff) <= m_lengthOfDeformation && m_versus == INNER) {
      diff *= (1.0 / m_lengthOfDeformation) * c_maxLenghtOfGaussian;
      outVal = gaussianPotential(diff);
    } else if (m_versus == OUTER) {
      double valForGaussian = -c_maxLenghtOfGaussian +
                              2 * c_maxLenghtOfGaussian /
                                  m_lengthOfDeformation *
                                  strokeLengthAtParameter;
      outVal = 1.0 - gaussianPotential(valForGaussian);
    }

    TPointD cp = convert(s.getControlPoint(n));
    TPointD p  = cp;

    TRotation rot(*m_vect, outVal * rad2degree(m_angle));

    p = rot * p;

    return TThickPoint(p - cp, 0.0);
  }

  return TThickPoint();
}
Ejemplo n.º 5
0
	void setPoint(const TPointD &p)
	{
		TThickPoint point = m_stroke->getControlPoint(m_index);
		point.x = p.x;
		point.y = p.y;
		m_stroke->setControlPoint(m_index, point);
	}
Ejemplo n.º 6
0
TThickPoint ControlPointEditorStroke::getSpeedOutPoint(int index) const {
  TStroke *stroke = getStroke();
  assert(stroke && 0 <= index && index < (int)m_controlPoints.size());

  ControlPoint cp = m_controlPoints[index];
  return stroke->getControlPoint(cp.m_pointIndex) + cp.m_speedOut;
}
Ejemplo n.º 7
0
void ControlPointEditorStroke::resetControlPoints() {
  TStroke *stroke = getStroke();
  if (!stroke) return;
  m_controlPoints.clear();
  int i;
  int cpCount = stroke->getControlPointCount();
  if (cpCount == 3) {
    const TThickQuadratic *chunk = stroke->getChunk(0);
    if (chunk->getP0() == chunk->getP1() &&
        chunk->getP0() == chunk->getP2())  // E' un punto
    {
      m_controlPoints.push_back(
          ControlPoint(0, TPointD(0.0, 0.0), TPointD(0.0, 0.0), true));
      return;
    }
  }
  for (i = 0; i < cpCount; i = i + 4) {
    TThickPoint speedIn, speedOut;
    bool isPickOut    = false;
    TThickPoint p     = stroke->getControlPoint(i);
    TThickPoint precP = stroke->getControlPoint(i - 1);
    TThickPoint nextP = stroke->getControlPoint(i + 1);
    if (0 < i && i < cpCount - 1)  // calcola speedIn e speedOut
    {
      speedIn  = p - precP;
      speedOut = nextP - p;
    }
    if (i == 0)  // calcola solo lo speedOut
    {
      speedOut                  = nextP - p;
      if (isSelfLoop()) speedIn = p - stroke->getControlPoint(cpCount - 2);
    }
    if (i == cpCount - 1)  // calcola solo lo speedIn
      speedIn = p - precP;
    if (i == cpCount - 1 && isSelfLoop())
      break;  // Se lo stroke e' selfLoop inserisco solo il primo dei due punti
              // coincidenti

    bool isCusp = ((i != 0 && i != cpCount - 1) || (isSelfLoop() && i == 0))
                      ? isCuspPoint(precP, p, nextP)
                      : true;
    m_controlPoints.push_back(ControlPoint(i, speedIn, speedOut, isCusp));
  }
}
Ejemplo n.º 8
0
bool PinchTool::keyDown(int key,
						TUINT32 flags,
						const TPoint &pos)
{
	m_deformation->reset();

#if 0
  char c = (char)key;
  if(c == 'p' ||
     c == 'P' )
  {
    TVectorImageP vimage(getImage());      
    if(!vimage)
      return false;
    
    char  fileName[] = {"c:\\toonz_input.sdd"};
    ofstream  out_file(fileName);
    if(!out_file)
    {
      cerr<<"Error on opening: "<<fileName<<endl;
      return false;
    }
    
    out_file<<"# VImage info\n";
    out_file<<"# Number of stroke:\n";
    const int max_number_of_strokes = vimage->getStrokeCount();
    out_file<<max_number_of_strokes<<endl;
    int number_of_strokes = 0;
    const int cp_for_row=3;
    while( number_of_strokes<max_number_of_strokes)
    {
      TStroke* ref = vimage->getStroke(number_of_strokes);
      out_file<<endl;
      out_file<<"# Number of control points for stroke:\n";
      const int max_number_of_cp = ref->getControlPointCount();
      out_file<<max_number_of_cp <<endl;
      out_file<<"# Control Points:\n";
      int number_of_cp=0;
      while( number_of_cp<max_number_of_cp )
      {
        out_file<<ref->getControlPoint(number_of_cp)<<" ";
        if(!((number_of_cp+1)%cp_for_row)) // add a new line after ten points
          out_file<<endl;
        number_of_cp++;
      }
      out_file<<endl;
      number_of_strokes++;
    }
  }
#endif
	return true;
}
Ejemplo n.º 9
0
TThickPoint ControlPointEditorStroke::getPureDependentPoint(int index) const {
  TStroke *stroke = getStroke();
  if (!stroke) return TThickPoint();
  bool selfLoop = isSelfLoop();
  int cpCount = selfLoop ? m_controlPoints.size() + 1 : m_controlPoints.size();
  int nextIndex  = (selfLoop && index == cpCount - 2) ? 0 : index + 1;
  int pointIndex = m_controlPoints[index].m_pointIndex;

  TThickPoint oldP(stroke->getControlPoint(pointIndex + 2));
  TPointD oldSpeedOutP = stroke->getControlPoint(pointIndex + 1);
  TPointD oldSpeedInP  = stroke->getControlPoint(pointIndex + 3);

  double dist = tdistance(oldSpeedOutP, oldSpeedInP);
  double t = (dist > 1e-4) ? tdistance(oldSpeedInP, convert(oldP)) / dist : 0.5;

  TPointD speedOutPoint(getSpeedOutPoint(index));
  TPointD nextSpeedInPoint(getSpeedInPoint(nextIndex));

  return TThickPoint((1 - t) * nextSpeedInPoint + t * speedOutPoint,
                     oldP.thick);

  // return TThickPoint(0.5 * (speedOutPoint + nextSpeedInPoint), oldThick);
}
Ejemplo n.º 10
0
TThickPoint TStrokePointDeformation::getDisplacementForControlPoint(
    const TStroke &stroke, UINT n) const {
  // riferimento ad un punto ciccione della stroke
  TPointD pntOfStroke(convert(stroke.getControlPoint(n)));

  double d = tdistance(pntOfStroke, m_imp->m_circleCenter);

  if (m_imp->m_vect)
    return m_imp->m_potential->value(d) * TThickPoint(*m_imp->m_vect, 0);
  else {
    double outVal = m_imp->m_potential->value(d);

    return TThickPoint(outVal, outVal, 0);
  }
}
Ejemplo n.º 11
0
void ControlPointEditorStroke::getDependentPoints(
    int index, std::vector<std::pair<int, TThickPoint>> &points) const {
  TStroke *stroke = getStroke();
  if (!stroke) return;

  int cpCount = m_controlPoints.size();
  if (index == cpCount && isSelfLoop())  // strange, but was treated...
    index = 0;

  if (index == 0 && cpCount == 1) {
    // Single point case
    TStroke *stroke = getStroke();
    TThickPoint pos(stroke->getControlPoint(m_controlPoints[0].m_pointIndex));

    points.push_back(std::make_pair(1, pos));
    points.push_back(std::make_pair(2, pos));
    return;
  }

  int prev = prevIndex(index);
  if (prev >= 0) {
    int prevPointIndex = m_controlPoints[prev].m_pointIndex;

    if (isSpeedOutLinear(prev))
      points.push_back(
          std::make_pair(prevPointIndex + 1, getSpeedOutPoint(prev)));
    points.push_back(
        std::make_pair(prevPointIndex + 2, getPureDependentPoint(prev)));
    points.push_back(
        std::make_pair(prevPointIndex + 3, getSpeedInPoint(index)));
  }

  int next = nextIndex(index);
  if (next >= 0) {
    int pointIndex = m_controlPoints[index].m_pointIndex;

    points.push_back(std::make_pair(pointIndex + 1, getSpeedOutPoint(index)));
    points.push_back(
        std::make_pair(pointIndex + 2, getPureDependentPoint(index)));
    if (isSpeedInLinear(next))
      points.push_back(std::make_pair(pointIndex + 3, getSpeedInPoint(next)));
  }
}
Ejemplo n.º 12
0
void ControlPointEditorStroke::moveSingleControlPoint(int index,
                                                      const TPointD &delta) {
  TStroke *stroke = getStroke();
  if (!stroke) return;

  int pointIndex = m_controlPoints[index].m_pointIndex;
  assert(stroke && 0 <= pointIndex &&
         pointIndex < stroke->getControlPointCount());

  bool selfLoop = isSelfLoop();
  int cpCount = selfLoop ? m_controlPoints.size() + 1 : m_controlPoints.size();

  TThickPoint p = stroke->getControlPoint(pointIndex);
  p             = TThickPoint(p + delta, p.thick);
  stroke->setControlPoint(pointIndex, p);
  if (pointIndex == 0 && selfLoop)
    stroke->setControlPoint(stroke->getControlPointCount() - 1, p);

  // Directions must be recalculated in the linear cases
  if ((selfLoop || index > 0) && isSpeedInLinear(index)) {
    setLinearSpeedIn(index, true, false);

    // Furthermore, if the NEIGHBOUR point is linear, it has to be
    // recalculated too
    int prevIndex = (selfLoop && index == 0) ? cpCount - 2 : index - 1;
    if (m_controlPoints[prevIndex].m_isCusp && isSpeedOutLinear(prevIndex))
      setLinearSpeedOut(prevIndex, true, false);
  }
  if ((selfLoop || index < cpCount - 1) && isSpeedOutLinear(index)) {
    setLinearSpeedOut(index, true, false);

    int nextIndex = (selfLoop && index == cpCount - 2) ? 0 : index + 1;
    if (m_controlPoints[nextIndex].m_isCusp && isSpeedInLinear(nextIndex))
      setLinearSpeedIn(nextIndex, true, false);
  }
}
Ejemplo n.º 13
0
ControlPointEditorStroke::PointType ControlPointEditorStroke::getPointTypeAt(
    const TPointD &pos, double &distance2, int &index) const {
  TStroke *stroke = getStroke();
  if (!stroke) return NONE;
  double w              = stroke->getW(pos);
  TPointD p             = stroke->getPoint(w);
  double strokeDistance = tdistance2(p, pos);

  int precPointIndex     = -1;
  double minPrecDistance = 0;
  double minDistance2    = distance2;
  index                  = -1;
  PointType type         = NONE;
  int cpCount            = m_controlPoints.size();
  int i;
  for (i = 0; i < cpCount; i++) {
    ControlPoint cPoint = m_controlPoints[i];
    TPointD point       = stroke->getControlPoint(cPoint.m_pointIndex);
    double cpDistance2  = tdistance2(pos, point);
    double distanceIn2  = !isSpeedInLinear(i)
                             ? tdistance2(pos, point - cPoint.m_speedIn)
                             : cpDistance2 + 1;
    double distanceOut2 = !isSpeedOutLinear(i)
                              ? tdistance2(pos, point + cPoint.m_speedOut)
                              : cpDistance2 + 1;
    if (i == 0 && !isSelfLoop())
      distanceIn2 = std::max(cpDistance2, distanceOut2) + 1;
    if (i == cpCount - 1 && !isSelfLoop())
      distanceOut2 = std::max(cpDistance2, distanceIn2) + 1;

    if (cpDistance2 < distanceIn2 && cpDistance2 < distanceOut2 &&
        (cpDistance2 < minDistance2 || index < 0)) {
      minDistance2 = cpDistance2;
      index        = i;
      type         = CONTROL_POINT;
    } else if (distanceIn2 < cpDistance2 && distanceIn2 < distanceOut2 &&
               (distanceIn2 < minDistance2 || index < 0)) {
      minDistance2 = distanceIn2;
      index        = i;
      type         = SPEED_IN;
    } else if (distanceOut2 < cpDistance2 && distanceOut2 < distanceIn2 &&
               (distanceOut2 < minDistance2 || index < 0)) {
      minDistance2 = distanceOut2;
      index        = i;
      type         = SPEED_OUT;
    }

    double cpw =
        stroke->getParameterAtControlPoint(m_controlPoints[i].m_pointIndex);
    if (w <= cpw) continue;
    double precDistance = w - cpw;
    if (precPointIndex < 0 || precDistance < minPrecDistance) {
      precPointIndex  = i;
      minPrecDistance = precDistance;
    }
  }

  if (minDistance2 < distance2)
    distance2 = minDistance2;
  else if (strokeDistance > distance2) {
    distance2 = strokeDistance;
    index     = -1;
    type      = NONE;
  } else {
    distance2 = minPrecDistance;
    index     = precPointIndex;
    type      = SEGMENT;
  }

  return type;
}
Ejemplo n.º 14
0
	TPointD getPoint() const
	{
		return m_stroke->getControlPoint(m_index);
	}
Ejemplo n.º 15
0
int ControlPointEditorStroke::addControlPoint(const TPointD &pos) {
  TStroke *stroke = getStroke();
  if (!stroke) return -1;
  double d = 0.01;
  int indexAtPos;
  int cpCount = stroke->getControlPointCount();
  if (cpCount <= 3)  // e' un unico chunk e in questo caso rappresenta un punto
  {
    getPointTypeAt(pos, d, indexAtPos);
    return indexAtPos;
  }

  double w       = stroke->getW(pos);
  int pointIndex = stroke->getControlPointIndexAfterParameter(w);

  int i, index;
  for (i = 0; i < getControlPointCount(); i++) {
    // Cerco il ControlPoint corrispondente all'indice pointIndex. OSS.:
    // Effettuo il
    // controllo da zero a getControlPointCount()-1 per gestire il caso del
    // selfLoop
    if (pointIndex == m_controlPoints[i].m_pointIndex + 1 ||
        pointIndex == m_controlPoints[i].m_pointIndex + 2 ||
        pointIndex == m_controlPoints[i].m_pointIndex + 3 ||
        pointIndex == m_controlPoints[i].m_pointIndex + 4)
      index = i;
  }

  ControlPoint precCp = m_controlPoints[index];
  assert(precCp.m_pointIndex >= 0);
  std::vector<TThickPoint> points;

  for (i = 0; i < cpCount; i++) {
    if (i != precCp.m_pointIndex + 1 && i != precCp.m_pointIndex + 2 &&
        i != precCp.m_pointIndex + 3)
      points.push_back(stroke->getControlPoint(i));
    if (i == precCp.m_pointIndex + 2) {
      bool isBeforePointLinear = isSpeedOutLinear(index);
      int nextIndex =
          (isSelfLoop() && index == m_controlPoints.size() - 1) ? 0 : index + 1;
      bool isNextPointLinear =
          nextIndex < (int)m_controlPoints.size() && isSpeedInLinear(nextIndex);

      TThickPoint a0 = stroke->getControlPoint(precCp.m_pointIndex);
      TThickPoint a1 = stroke->getControlPoint(precCp.m_pointIndex + 1);
      TThickPoint a2 = stroke->getControlPoint(precCp.m_pointIndex + 2);
      TThickPoint a3 = stroke->getControlPoint(precCp.m_pointIndex + 3);
      TThickPoint a4 = stroke->getControlPoint(precCp.m_pointIndex + 4);
      double dist2   = tdistance2(pos, TPointD(a2));
      TThickPoint d0, d1, d2, d3, d4, d5, d6;

      if (isBeforePointLinear && isNextPointLinear) {
        // Se sono entrambi i punti lineari  inserisco un punto lineare
        d0 = a1;
        d3 = stroke->getThickPoint(w);
        d6 = a3;
        d2 = computeLinearPoint(d0, d3, 0.01, true);   // SpeedIn
        d4 = computeLinearPoint(d3, d6, 0.01, false);  // SpeedOut
        d1 = 0.5 * (d0 + d2);
        d5 = 0.5 * (d4 + d6);
      } else if (dist2 < 32) {
        // Sono molto vicino al punto che non viene visualizzato
        TThickPoint b0 = 0.5 * (a0 + a1);
        TThickPoint b1 = 0.5 * (a2 + a1);
        TThickPoint c0 = 0.5 * (b0 + b1);

        TThickPoint b2 = 0.5 * (a2 + a3);
        TThickPoint b3 = 0.5 * (a3 + a4);

        TThickPoint c1 = 0.5 * (b2 + b3);
        d0             = b0;
        d1             = c0;
        d2             = b1;
        d3             = a2;
        d4             = b2;
        d5             = c1;
        d6             = b3;
      } else {
        bool isInFirstChunk = true;
        if (pointIndex > precCp.m_pointIndex + 2) {
          // nel caso in cui sono nel secondo chunk scambio i punti
          a0 = a4;
          std::swap(a1, a3);
          isInFirstChunk = false;
        }

        double w0 = (isSelfLoop() && precCp.m_pointIndex + 4 == cpCount - 1 &&
                     !isInFirstChunk)
                        ? 1
                        : stroke->getW(a0);
        double w1 = stroke->getW(a2);
        double t  = (w - w0) / (w1 - w0);

        TThickPoint p  = stroke->getThickPoint(w);
        TThickPoint b0 = TThickPoint((1 - t) * a0 + t * a1,
                                     (1 - t) * a0.thick + t * a1.thick);
        TThickPoint b1 = TThickPoint((1 - t) * a1 + t * a2,
                                     (1 - t) * a1.thick + t * a2.thick);
        TThickPoint c0 =
            TThickPoint(0.5 * a0 + 0.5 * b0, (1 - t) * a0.thick + t * b0.thick);
        TThickPoint c1 =
            TThickPoint(0.5 * b0 + 0.5 * p, (1 - t) * b0.thick + t * p.thick);
        TThickPoint c2 =
            TThickPoint(0.5 * c0 + 0.5 * c1, (1 - t) * c0.thick + t * c1.thick);

        d0 = (isInFirstChunk) ? c0 : a3;
        d1 = (isInFirstChunk) ? c2 : a2;
        d2 = (isInFirstChunk) ? c1 : b1;
        d3 = p;
        d4 = (isInFirstChunk) ? b1 : c1;
        d5 = (isInFirstChunk) ? a2 : c2;
        d6 = (isInFirstChunk) ? a3 : c0;
      }
      if (isBeforePointLinear && !isNextPointLinear)
        d1 = computeLinearPoint(d0, d2, 0.01, false);
      else if (isNextPointLinear && !isBeforePointLinear)
        d5 = computeLinearPoint(d4, d6, 0.01, true);
      points.push_back(d0);
      points.push_back(d1);
      points.push_back(d2);
      points.push_back(d3);
      points.push_back(d4);
      points.push_back(d5);
      points.push_back(d6);
    }
  }

  stroke->reshape(&points[0], points.size());
  resetControlPoints();

  getPointTypeAt(pos, d, indexAtPos);
  return indexAtPos;
}
Ejemplo n.º 16
0
	void leftButtonUp(const TPointD &, const TMouseEvent &)
	{
		if (!m_active)
			return;

		m_active = false;
		m_pointAtMouseDown = m_pointAtMove = TConsts::napd;

		TStroke *ref;

		TVectorImageP vi = TImageP(getImage(true));
		if (!vi)
			return;
		QMutexLocker lock(vi->getMutex());
		UINT i, j;

		for (i = 0; i < m_strokeHit.size(); ++i) {
			ref = m_strokeHit[i];
			ref->enableComputeOfCaches();
			ref->reduceControlPoints(getPixelSize() * ReduceControlPointCorrection, *(m_hitStrokeCorners[i]));
			// vi->validateRegionEdges(ref, false);
		}
		clearPointerContainer(m_hitStrokeCorners);
		m_hitStrokeCorners.clear();

		UINT count = 0;
		for (i = 0; i < m_strokeToModify.size(); ++i) {
			// recupero la stroke collection
			MagnetTool::strokeCollection &sc = m_strokeToModify[i];

			for (j = 0; j < sc.m_splittedToMove.size(); ++j) {
				ref = sc.m_splittedToMove[j];
				ref->enableComputeOfCaches();
				ref->reduceControlPoints(getPixelSize() * ReduceControlPointCorrection, *(m_strokeToModifyCorners[count++]));
			}

			// ricostruisco una stroke con quella data
			ref = merge(sc.m_splitted);

			if (sc.m_parent->isSelfLoop()) {
				int cpCount = ref->getControlPointCount();
				TThickPoint p1 = ref->getControlPoint(0);
				TThickPoint p2 = ref->getControlPoint(cpCount - 1);
				TThickPoint midP = (p1 + p2) * 0.5;
				ref->setControlPoint(0, midP);
				ref->setControlPoint(cpCount - 1, midP);
				ref->setSelfLoop(true);
			}

			sc.m_parent->swapGeometry(*ref);

			delete ref;							  // elimino la curva temporanea
			clearPointerContainer(sc.m_splitted); // pulisco le stroke trovate con lo split
			sc.m_splittedToMove.clear();		  // pulisco il contenitore ( le stroke
												  // che erano contenute qua sono state
												  // eliminate nella clearPointer....
		}
		clearPointerContainer(m_strokeToModifyCorners);
		m_strokeToModifyCorners.clear();

		for (i = 0; i < vi->getStrokeCount(); ++i) {
			ref = vi->getStroke(i);
			ref->invalidate();
		}

		vi->notifyChangedStrokes(m_changedStrokes, m_oldStrokesArray);
		notifyImageChanged();
		if (m_undo)
			TUndoManager::manager()->add(m_undo);
		m_undo = 0;
		clearPointerContainer(m_oldStrokesArray);
		m_oldStrokesArray.clear();
		invalidate();
	};
Ejemplo n.º 17
0
TThickPoint ControlPointEditorStroke::getControlPoint(int index) const {
  TStroke *stroke = getStroke();
  assert(stroke && 0 <= index && index < (int)m_controlPoints.size());
  return stroke->getControlPoint(m_controlPoints[index].m_pointIndex);
}