void StrokeSelection::changeColorStyle(int styleIndex)
{
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
	if (!tool)
		return;
	TVectorImageP img(tool->getImage(true));
	if (!img)
		return;
	TPalette *palette = img->getPalette();
	TColorStyle *cs = palette->getStyle(styleIndex);
	if (!cs->isStrokeStyle())
		return;
	if (m_indexes.empty())
		return;

	UndoSetStrokeStyle *undo = new UndoSetStrokeStyle(img, styleIndex);
	std::set<int>::iterator it;
	for (it = m_indexes.begin(); it != m_indexes.end(); ++it) {
		int index = *it;
		assert(0 <= index && index < (int)img->getStrokeCount());
		TStroke *stroke = img->getStroke(index);
		undo->addStroke(stroke);
		stroke->setStyle(styleIndex);
	}

	tool->notifyImageChanged();
	TUndoManager::manager()->add(undo);
}
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);
}
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);
}
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;
}
示例#5
0
void ControlPointEditorStroke::updatePoints() {
  TStroke *stroke = getStroke();
  if (!stroke) return;
  bool selfLoop = isSelfLoop();
  // Se e' rimasto un unico punto non ha senso che la stroke sia selfloop
  if (selfLoop && m_controlPoints.size() == 1) {
    stroke->setSelfLoop(false);
    selfLoop = false;
  }

  // Se e' self loop  devo aggiungere un punto in piu' al cpCount
  std::vector<TThickPoint> points;

  int cpCount = selfLoop ? m_controlPoints.size() + 1 : m_controlPoints.size();
  if (cpCount == 1)
    // Single point case
    points.resize(3, getControlPoint(0));
  else {
    std::vector<std::pair<int, TThickPoint>> dependentPoints;

    points.push_back(getControlPoint(0));
    points.push_back(getSpeedOutPoint(0));

    int i, pointIndex, currPointIndex = m_controlPoints[0].m_pointIndex + 1;
    for (i = 1; i < cpCount; ++i) {
      bool isLastSelfLoopPoint = (selfLoop && i == cpCount - 1);
      int index                = isLastSelfLoopPoint ? 0 : i;

      TThickPoint p = getControlPoint(index);
      pointIndex    = isLastSelfLoopPoint ? getStroke()->getControlPointCount()
                                       : m_controlPoints[index].m_pointIndex;

      dependentPoints.clear();
      getDependentPoints(index, dependentPoints);

      int j;
      for (j = 0; j < (int)dependentPoints.size() &&
                  dependentPoints[j].first < pointIndex;
           j++) {
        if (currPointIndex < dependentPoints[j].first) {
          currPointIndex = dependentPoints[j].first;
          points.push_back(dependentPoints[j].second);
        }
      }

      points.push_back(p);

      for (; j < (int)dependentPoints.size(); j++) {
        if (currPointIndex < dependentPoints[j].first) {
          currPointIndex = dependentPoints[j].first;
          points.push_back(dependentPoints[j].second);
        }
      }
    }
  }

  stroke->reshape(&points[0], points.size());
  m_vi->notifyChangedStrokes(m_strokeIndex);
}
/*-- (StylePickerTool内で)LineとAreaを切り替えてPickできる。mode: 0=Area, 1=Line, 2=Line&Areas(default)  --*/
int StylePicker::pickStyleId(const TPointD &pos, double radius2, int mode) const
{
	int styleId = 0;
	if (TToonzImageP ti = m_image) {
		TRasterCM32P ras = ti->getRaster();
		TPoint point = getRasterPoint(pos);
		if (!ras->getBounds().contains(point))
			return -1;
		TPixelCM32 col = ras->pixels(point.y)[point.x];

		switch (mode) {
		case 0: //AREAS
			styleId = col.getPaint();
			break;
		case 1: //LINES
			styleId = col.getInk();
			break;
		case 2: //ALL (Line & Area)
		default:
			styleId = col.isPurePaint() ? col.getPaint() : col.getInk();
			break;
		}
	} else if (TRasterImageP ri = m_image) {
		const TPalette *palette = m_palette.getPointer();
		if (!palette)
			return -1;
		TRaster32P ras = ri->getRaster();
		if (!ras)
			return -1;
		TPoint point = getRasterPoint(pos);
		if (!ras->getBounds().contains(point))
			return -1;
		TPixel32 col = ras->pixels(point.y)[point.x];
		styleId = palette->getClosestStyle(col);
	} else if (TVectorImageP vi = m_image) {
		// prima cerca lo stile della regione piu' vicina
		TRegion *r = vi->getRegion(pos);
		if (r)
			styleId = r->getStyle();
		// poi cerca quello della stroke, ma se prima aveva trovato una regione, richiede che
		// il click sia proprio sopra la stroke, altrimenti cerca la stroke piu' vicina (max circa 10 pixel)
		const double maxDist2 = (styleId == 0) ? 100.0 * radius2 : 0;
		bool strokeFound;
		double dist2, w, thick;
		UINT index;
		//!funzionerebbe ancora meglio con un getNearestStroke che considera
		//la thickness, cioe' la min distance dalla outline e non dalla centerLine
		strokeFound = vi->getNearestStroke(pos, w, index, dist2);
		if (strokeFound) {
			TStroke *stroke = vi->getStroke(index);
			thick = stroke->getThickPoint(w).thick;
			if (dist2 - thick * thick < maxDist2) {
				assert(stroke);
				styleId = stroke->getStyle();
			}
		}
	}
	return styleId;
}
示例#7
0
bool TRegion::Imp::contains(const TStroke &s, bool mayIntersect) const
{
	if (!getBBox().contains(s.getBBox()))
		return false;
	if (mayIntersect && thereAreintersections(s))
		return false;

	return contains(s.getThickPoint(0.5));
}
示例#8
0
double TStrokeBenderDeformation::getDelta(const TStroke &s, double w) const {
  double totalLenght = s.getLength();

  if (totalLenght != 0) {
    double val = s.getLength(w) / totalLenght * (M_PI * 10.0);

    return sin(val);
  }
  return 0;
}
示例#9
0
bool PinchTool::moveCursor(const TPointD &pos)
{
	double w = 0.0;
	TStroke *stroke = getClosestStroke(pos, w);
	if (!stroke)
		return false;

	m_cursor = stroke->getThickPoint(w);
	return true;
}
示例#10
0
TRect TRasterImageUtils::addStroke(const TRasterImageP &ri, TStroke *stroke, TRectD clip,
								   double opacity, bool doAntialiasing)
{
	TStroke *s = new TStroke(*stroke);
	TPoint riCenter = ri->getRaster()->getCenter();
	s->transform(TTranslation(riCenter.x, riCenter.y));
	TRect rect = fastAddInkStroke(ri, s, clip, opacity, doAntialiasing);
	rect -= riCenter;
	delete s;
	return rect;
}
示例#11
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();
}
示例#12
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;
}
示例#13
0
void ControlPointEditorStroke::updateDependentPoint(int index) {
  TStroke *stroke = getStroke();
  if (!stroke) return;

  std::vector<std::pair<int, TThickPoint>> points;
  getDependentPoints(index, points);

  int i;
  for (i = 0; i < (int)points.size(); i++)
    stroke->setControlPoint(points[i].first, points[i].second);

  m_vi->notifyChangedStrokes(m_strokeIndex);
}
示例#14
0
double TStrokePointDeformation::getDelta(const TStroke &stroke,
                                         double w) const {
  // reference to a thickpoint
  TThickPoint thickPnt = m_imp->m_vect ? stroke.getControlPointAtParameter(w)
                                       : stroke.getThickPoint(w);

  assert(thickPnt != TConsts::natp);

  TPointD pntOfStroke = convert(thickPnt);

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

  return m_imp->m_potential->gradient(d);
}
示例#15
0
TThickPoint TStrokeThicknessDeformation::getDisplacement(const TStroke &stroke,
                                                         double w) const {
  // potenziale exp^(-x^2) limitato tra
  // [-c_maxLenghtOfGaussian,c_maxLenghtOfGaussian]
  double diff = stroke.getLength(w);

  diff = diff - m_startParameter;

  if (fabs(diff) <= m_lengthOfDeformation) {
    // modulo il vettore spostamento in funzione  del potenziale
    //  il termine (1.0/m_lengthOfDeformation) * 3 scala
    //  il punto in diff su un sistema di coordinate
    //  normalizzato, associato con la curva exp^(-x^2)
    diff *= (1.0 / m_lengthOfDeformation) * c_maxLenghtOfGaussian;

    if (m_vect)
      return gaussianPotential(diff) * TThickPoint(*m_vect, 0);
    else {
      double outVal = gaussianPotential(diff);
      return TThickPoint(0, 0, outVal);
    }
  }

  return TThickPoint();
}
示例#16
0
//-----------------------------------------------------------------------------
TThickPoint TStrokeThicknessDeformation::getDisplacementForControlPoint(
    const TStroke &stroke, UINT n) const {
  // potenziale exp^(-x^2) limitato tra
  // [-c_maxLenghtOfGaussian,c_maxLenghtOfGaussian]
  double diff = stroke.getLengthAtControlPoint(n);

  diff = diff - m_startParameter;

  if (fabs(diff) <= m_lengthOfDeformation) {
    // modulo il vettore spostamento in funzione  del potenziale
    //  il termine (1.0/m_lengthOfDeformation) * 3 scala
    //  il punto in diff su un sistema di coordinate
    //  normalizzato, associato con la curva exp^(-x^2)
    diff *= (1.0 / m_lengthOfDeformation) * c_maxLenghtOfGaussian;

    TThickPoint delta;

    if (m_vect) {
      // tsign(m_vect->y) * 0.1
      delta =
          TThickPoint(0, 0, m_versus * norm(*m_vect) * gaussianPotential(diff));
    } else {
      double outVal = gaussianPotential(diff);
      delta         = TThickPoint(0, 0, outVal);
    }
    // TThickPoint cp = stroke.getControlPoint(n);
    // if(cp.thick + delta.thick<0.001) delta.thick = 0.001-cp.thick;
    return delta;
  }
  return TThickPoint();
}
示例#17
0
void ControlPointEditorStroke::setStroke(const TVectorImageP &vi,
                                         int strokeIndex) {
  m_strokeIndex = strokeIndex;
  m_vi          = vi;
  if (!vi || strokeIndex == -1) {
    m_controlPoints.clear();
    return;
  }
  TStroke *stroke              = getStroke();
  const TThickQuadratic *chunk = stroke->getChunk(0);
  if (stroke->getControlPointCount() == 3 && chunk->getP0() == chunk->getP1() &&
      chunk->getP0() == chunk->getP2()) {
    resetControlPoints();
    return;
  }
  adjustChunkParity();
  resetControlPoints();
}
bool SelfLoopDeformation::check(Context *dragger,
								DraggerStatus *status)
{
	assert(status && dragger && "Not dragger or status available");
	assert(!"SelfLoopDeformation::check not yet implemented!");
	//  lengthOfAction_ = status->lengthOfAction_;
	//  deformerSensibility_ = status->deformerSensibility_;
	//  stroke2move_ = status->stroke2change_;
	TStroke *s = stroke2move_;
	//  double &w = status->w_;

	if (s->isSelfLoop()) {
		//    dragger->changeDeformation(SelfLoopDeformation::instance());
		//    SelfLoopDeformation::instance()->activate(dragger,
		//                                              status);
		return true;
	}
	return false;
}
示例#19
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)));
  }
}
double ToonzExt::StrokeParametricDeformer::getDelta(const TStroke &stroke,
                                                    double w) const {
#if 0
  double  w0 = w;
  if(w0 == 1.0)
    return norm( stroke.getSpeed(1.0));
  double tmp = stroke.getLength(w0);
  tmp+=1.0;
  double w1 = stroke.getParameterAtLength(tmp);

  /*
  double  w1 = w + 0.01;  
  if(w1>1.0)
  {
    w0 = 1.0 - 0.01;
    w1 = 1.0;
  }
  */

  const double  dx = 1.0; //stroke.getLength(w0,w1);
  TThickPoint pnt = this->getDisplacement(stroke,w1) - 
                    this->getDisplacement(stroke,w0);

  double  dy =  sqrt( sq(pnt.x) + sq(pnt.y) + sq(pnt.thick) );

  assert(dx!=0.0);
  return dy/dx;

  /*
  // the increaser is wrong than this value need to be the deformation
  //  value 

  // is norm 
  TThickPoint pnt = this->getDisplacement(stroke,
                                          w);
  return sqrt( sq(pnt.x) + sq(pnt.y) + sq(pnt.thick) );

  //return pot_->gradient(w);
  */
#endif
  return this->getDisplacement(stroke, w).y;
}
示例#21
0
TThickPoint TStrokePointDeformation::getDisplacement(const TStroke &stroke,
                                                     double w) const {
  // riferimento ad un punto ciccione della stroke
  TThickPoint thickPnt = m_imp->m_vect ? stroke.getControlPointAtParameter(w)
                                       : stroke.getThickPoint(w);

  assert(thickPnt != TConsts::natp);

  TPointD pntOfStroke(convert(thickPnt));

  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);
  }
}
示例#22
0
void renormalizeImage(TVectorImage *vi)
{
	int i, j;
	int n = vi->getStrokeCount();
	std::vector<ControlPoint> points;
	points.reserve(n * 2);
	for (i = 0; i < n; i++) {
		TStroke *stroke = vi->getStroke(i);
		int m = stroke->getControlPointCount();
		if (m > 0) {
			if (m == 1)
				points.push_back(ControlPoint(stroke, 0));
			else {
				points.push_back(ControlPoint(stroke, 0));
				points.push_back(ControlPoint(stroke, m - 1));
			}
		}
	}
	int count = points.size();
	for (i = 0; i < count; i++) {
		ControlPoint &pi = points[i];
		TPointD posi = pi.getPoint();
		TPointD center = posi;
		std::vector<int> neighbours;
		neighbours.push_back(i);
		for (j = i + 1; j < count; j++) {
			TPointD posj = points[j].getPoint();
			double d = tdistance(posj, posi);
			if (d < 0.01) {
				neighbours.push_back(j);
				center += posj;
			}
		}
		int m = neighbours.size();
		if (m == 1)
			continue;
		center = center * (1.0 / m);
		for (j = 0; j < m; j++)
			points[neighbours[j]].setPoint(center);
	}
}
示例#23
0
TThickPoint TStrokeTwirlDeformation::getDisplacement(const TStroke &stroke,
                                                     double s) const {
  double outVal = 0;

  double distance2 =
      tdistance2(convert(stroke.getControlPointAtParameter(s)), m_center);

  if (distance2 <= m_innerRadius2)
    outVal = wyvillPotential(distance2, m_innerRadius2);

  return TThickPoint(m_vectorOfMovement * outVal, 0);
}
示例#24
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);
}
示例#25
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);
  }
}
示例#26
0
void TColorStyle::drawStroke(TFlash &flash, const TStroke *s) const {
  bool isCenterline = false;
  double minThickness, maxThickness = 0;
  std::wstring quality = flash.getLineQuality();
  double thickness     = computeAverageThickness(s, minThickness, maxThickness);
  if (minThickness == maxThickness && minThickness == 0) return;
  if (quality == TFlash::ConstantLines)
    isCenterline = true;
  else if (quality == TFlash::MixedLines &&
           (maxThickness == 0 || minThickness / maxThickness > 0.5))
    isCenterline = true;
  else if (quality == TFlash::VariableLines &&
           maxThickness - minThickness <
               0.16)  // Quando si salva il pli, si approssima al thick.
                      // L'errore di approx e' sempre 0.1568...
    isCenterline = true;
  // else	assert(false);

  flash.setFillColor(getAverageColor());
  // flash.setFillColor(TPixel::Red);

  TStroke *saux = const_cast<TStroke *>(s);
  if (isCenterline) {
    saux->setAverageThickness(thickness);
    flash.setThickness(s->getAverageThickness());
    flash.setLineColor(getAverageColor());
    flash.drawCenterline(s, false);
  } else {
    saux->setAverageThickness(0);
    if (!flash.drawOutline(saux)) {
      flash.setThickness(thickness);
      flash.setLineColor(getAverageColor());
      flash.drawCenterline(s, false);
    }
  }
}
示例#27
0
void ControlPointEditorStroke::deleteControlPoint(int index) {
  TStroke *stroke = getStroke();
  if (!stroke) return;

  assert(stroke && 0 <= index && index < (int)getControlPointCount());
  // E' un unico chunk e in questo caso rappresenta un punto
  if (stroke->getControlPointCount() <= 3 ||
      (isSelfLoop() && stroke->getControlPointCount() <= 5)) {
    m_controlPoints.clear();
    m_vi->deleteStroke(m_strokeIndex);
    return;
  }

  QList<int> newPointsIndex;
  int i;
  for (i = 0; i < (int)getControlPointCount() - 1; i++)
    newPointsIndex.push_back(m_controlPoints[i].m_pointIndex);

  m_controlPoints.removeAt(index);
  updatePoints();

  // Aggiorno gli indici dei punti nella stroke
  assert((int)newPointsIndex.size() == (int)getControlPointCount());
  for (i                            = 0; i < (int)getControlPointCount(); i++)
    m_controlPoints[i].m_pointIndex = newPointsIndex.at(i);

  int prev = prevIndex(index);
  if (prev >= 0 && isSpeedOutLinear(prev)) {
    setLinearSpeedOut(prev);
    updateDependentPoint(prev);
  }
  if (index < (int)m_controlPoints.size() && isSpeedInLinear(index)) {
    setLinearSpeedIn(index);
    updateDependentPoint(index);
  }
}
示例#28
0
double TStrokeParamDeformation::getDelta(const TStroke &stroke,
                                         double w) const {
  // potenziale exp^(-x^2) limitato tra
  // [-c_maxLenghtOfGaussian,c_maxLenghtOfGaussian]
  double diff = stroke.getLength(w);

  diff = diff - m_startParameter;
  if (fabs(diff) <= m_lengthOfDeformation) {
    // modulo il vettore spostamento in funzione  del potenziale
    //  il termine (1.0/m_lengthOfDeformation) * 3 scala
    //  il punto in diff su un sistema di coordinate
    //  normalizzato, associato con la curva exp^(-x^2)
    diff *= (1.0 / m_lengthOfDeformation) * c_maxLenghtOfGaussian;

    return derivateOfGaussianPotential(diff);
  }

  return 0;
}
示例#29
0
void ControlPointEditorStroke::adjustChunkParity() {
  TStroke *stroke = getStroke();
  if (!stroke) return;
  int firstChunk;
  int secondChunk = stroke->getChunkCount();
  int i;
  for (i = stroke->getChunkCount() - 1; i > 0; i--) {
    if (tdistance(stroke->getChunk(i - 1)->getP0(),
                  stroke->getChunk(i)->getP2()) < 0.5)
      continue;
    TPointD p0 = stroke->getChunk(i - 1)->getP1();
    TPointD p1 = stroke->getChunk(i - 1)->getP2();
    TPointD p2 = stroke->getChunk(i)->getP1();
    if (isCuspPoint(p0, p1, p2) || isLinearPoint(p0, p1, p2)) {
      firstChunk = i;
      insertPoint(stroke, firstChunk, secondChunk);
      secondChunk = firstChunk;
    }
  }
  insertPoint(stroke, 0, secondChunk);
}
示例#30
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));
  }
}