Blame synfig-studio/src/synfigapp/vectorizer/centerlineadjustments.cpp

Ankit Kumar Dwivedi ea8c72
/* === S Y N F I G ========================================================= */
Ankit Kumar Dwivedi ea8c72
/*!	\file centerlineadjustments.cpp
Ankit Kumar Dwivedi ea8c72
**	\brief centerlineadjustments File
Ankit Kumar Dwivedi ea8c72
**
Ankit Kumar Dwivedi ea8c72
**	$Id$
Ankit Kumar Dwivedi ea8c72
**
Ankit Kumar Dwivedi ea8c72
**	\legal
Ankit Kumar Dwivedi ea8c72
**	Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
Ankit Kumar Dwivedi ea8c72
**
Ankit Kumar Dwivedi ea8c72
**	This package is free software; you can redistribute it and/or
Ankit Kumar Dwivedi ea8c72
**	modify it under the terms of the GNU General Public License as
Ankit Kumar Dwivedi ea8c72
**	published by the Free Software Foundation; either version 2 of
Ankit Kumar Dwivedi ea8c72
**	the License, or (at your option) any later version.
Ankit Kumar Dwivedi ea8c72
**
Ankit Kumar Dwivedi ea8c72
**	This package is distributed in the hope that it will be useful,
Ankit Kumar Dwivedi ea8c72
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
Ankit Kumar Dwivedi ea8c72
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Ankit Kumar Dwivedi ea8c72
**	General Public License for more details.
Ankit Kumar Dwivedi ea8c72
**	\endlegal
Ankit Kumar Dwivedi ea8c72
*/
Ankit Kumar Dwivedi ea8c72
/* ========================================================================= */
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
/* === H E A D E R S ======================================================= */
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
#include "polygonizerclasses.h"
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
/* === U S I N G =========================================================== */
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
using namespace std;
Ankit Kumar Dwivedi ea8c72
using namespace etl;
Ankit Kumar Dwivedi ea8c72
using namespace studio;
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
/* === M A C R O S ========================================================= */
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
/* === G L O B A L S ======================================================= */
Ankit Kumar Dwivedi b29b8f
VectorizerCoreGlobals *globals;
Ankit Kumar Dwivedi b29b8f
std::vector<unsigned int=""> contourFamilyOfOrganized;</unsigned>
Ankit Kumar Dwivedi b29b8f
JointSequenceGraph *currJSGraph;
Ankit Kumar Dwivedi b29b8f
ContourFamily *currContourFamily;
Ankit Kumar Dwivedi b29b8f
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
/* === P R O C E D U R E S ================================================= */
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
/* === M E T H O D S ======================================================= */
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
/* === E N T R Y P O I N T ================================================= */
Ankit Kumar Dwivedi ea8c72
//--------------------------------------
Ankit Kumar Dwivedi ea8c72
//      Skeleton re-organization
Ankit Kumar Dwivedi ea8c72
//--------------------------------------
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
// EXPLANATION:  The raw skeleton data obtained from StraightSkeletonizer
luz.paz 7040b8
// class need to be grouped in joints and sequences before proceeding with
Ankit Kumar Dwivedi ea8c72
// conversion in quadratics - which works on single sequences.
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
// NOTE: Due to maxHeight, we have to assume that a single SkeletonGraph can
Ankit Kumar Dwivedi ea8c72
// hold
Ankit Kumar Dwivedi ea8c72
// more connected graphs at once.
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
// a) Isolate graph-like part of skeleton
Ankit Kumar Dwivedi ea8c72
// b) Retrieve remaining single sequences.
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
typedef std::map<uint, std::less<uint="" uint,="">> uintMap;</uint,>
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
// void organizeGraphs(SkeletonList* skeleton)
Ankit Kumar Dwivedi d388d7
void studio::organizeGraphs(SkeletonList *skeleton, VectorizerCoreGlobals &g) 
Ankit Kumar Dwivedi b29b8f
{
Ankit Kumar Dwivedi ea8c72
  globals = &g;
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
  SkeletonList::iterator currGraphPtr;
Ankit Kumar Dwivedi ea8c72
  Sequence currSequence;
Ankit Kumar Dwivedi ea8c72
  uintMap jointsMap;
Ankit Kumar Dwivedi ea8c72
  UINT i, j;
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
  UINT counter = 0;  // We also count current graph number, to associate
Ankit Kumar Dwivedi ea8c72
  // organized graphs to their contour family
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
  contourFamilyOfOrganized.clear();
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi 4792ed
  for (currGraphPtr = skeleton->begin(); currGraphPtr != skeleton->end();++currGraphPtr) 
Ankit Kumar Dwivedi 4792ed
  {
Ankit Kumar Dwivedi ea8c72
    SkeletonGraph &currGraph   = **currGraphPtr;
Ankit Kumar Dwivedi ea8c72
    currSequence.m_graphHolder = &currGraph;
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
    // Separate single Points - can happen only when a single node gets stored
Ankit Kumar Dwivedi ea8c72
    // in a SkeletonGraph.
Ankit Kumar Dwivedi 2a7b0e
    if (currGraph.getNodesCount() == 1) 
Ankit Kumar Dwivedi 2a7b0e
    {
Ankit Kumar Dwivedi ea8c72
      globals->singlePoints.push_back(*currGraph.getNode(0));
Ankit Kumar Dwivedi ea8c72
      ++counter;
Ankit Kumar Dwivedi ea8c72
      continue;
Ankit Kumar Dwivedi ea8c72
    }
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
    // Discriminate between graphs, two-endpoint single sequences, and circular
Ankit Kumar Dwivedi ea8c72
    // ones
Ankit Kumar Dwivedi ea8c72
    bool has1DegreePoint = 0;
Ankit Kumar Dwivedi ea8c72
    for (i = 0; i < currGraph.getNodesCount(); ++i)
Ankit Kumar Dwivedi b29b8f
    {
Ankit Kumar Dwivedi b29b8f
        if (currGraph.getNode(i).degree() != 2)
Ankit Kumar Dwivedi b29b8f
        {
Ankit Kumar Dwivedi b29b8f
            if (currGraph.getNode(i).degree() == 1)
Ankit Kumar Dwivedi b29b8f
                has1DegreePoint = 1;
Ankit Kumar Dwivedi b29b8f
            else
Ankit Kumar Dwivedi b29b8f
                goto _graph;
Ankit Kumar Dwivedi b29b8f
        }
Ankit Kumar Dwivedi b29b8f
    }
Ankit Kumar Dwivedi b29b8f
      
Ankit Kumar Dwivedi ea8c72
    if (has1DegreePoint)
Ankit Kumar Dwivedi ea8c72
      goto _two_endpoint;
Ankit Kumar Dwivedi ea8c72
    else
Ankit Kumar Dwivedi ea8c72
      goto _circulars;
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
  _two_endpoint : {
Ankit Kumar Dwivedi ea8c72
    // Find head
Ankit Kumar Dwivedi b29b8f
    for (i = 0; currGraph.getNode(i).degree() != 1; ++i);
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
    currSequence.m_head     = i;
Ankit Kumar Dwivedi ea8c72
    currSequence.m_headLink = 0;
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
    // Find tail
Ankit Kumar Dwivedi b29b8f
    for (++i; i < currGraph.getNodesCount() && currGraph.getNode(i).degree() == 2;  ++i);
Ankit Kumar Dwivedi b29b8f
Ankit Kumar Dwivedi ea8c72
    currSequence.m_tail     = i;
Ankit Kumar Dwivedi ea8c72
    currSequence.m_tailLink = 0;
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
    globals->singleSequences.push_back(currSequence);
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
    ++counter;
Ankit Kumar Dwivedi ea8c72
    continue;
Ankit Kumar Dwivedi ea8c72
  }
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
  _graph : {
Ankit Kumar Dwivedi ea8c72
    // Organize Graph-like part
Ankit Kumar Dwivedi ea8c72
    globals->organizedGraphs.push_back(JointSequenceGraph());
Ankit Kumar Dwivedi ea8c72
    JointSequenceGraph &JSGraph = globals->organizedGraphs.back();
Ankit Kumar Dwivedi ea8c72
    contourFamilyOfOrganized.push_back(counter);
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
    jointsMap.clear();
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
    // Gather all sequence extremities
Ankit Kumar Dwivedi b29b8f
    for (i = 0; i < currGraph.getNodesCount(); ++i) 
Ankit Kumar Dwivedi b29b8f
    {
Ankit Kumar Dwivedi b29b8f
      if (currGraph.getNode(i).degree() != 2) 
Ankit Kumar Dwivedi b29b8f
      {
Ankit Kumar Dwivedi ea8c72
        j = JSGraph.newNode(i);
Ankit Kumar Dwivedi ea8c72
        // Using a map to keep one-to-one relation between j and i
Ankit Kumar Dwivedi ea8c72
        jointsMap.insert(uintMap::value_type(i, j));
Ankit Kumar Dwivedi ea8c72
      }
Ankit Kumar Dwivedi ea8c72
    }
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
    // Extract Sequences
Ankit Kumar Dwivedi b29b8f
    for (i = 0; i < JSGraph.getNodesCount(); ++i) 
Ankit Kumar Dwivedi b29b8f
    {
Ankit Kumar Dwivedi ea8c72
      UINT joint = *JSGraph.getNode(i);
Ankit Kumar Dwivedi b29b8f
      for (j = 0; j < currGraph.getNode(joint).getLinksCount(); ++j) 
Ankit Kumar Dwivedi b29b8f
      {
Ankit Kumar Dwivedi ea8c72
        currSequence.m_head     = joint;
Ankit Kumar Dwivedi ea8c72
        currSequence.m_headLink = j;
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
        // Seek tail
Ankit Kumar Dwivedi ea8c72
        UINT oldNode  = joint,
Ankit Kumar Dwivedi ea8c72
             thisNode = currGraph.getNode(joint).getLink(j).getNext();
Ankit Kumar Dwivedi b29b8f
        while (currGraph.getNode(thisNode).degree() == 2) 
Ankit Kumar Dwivedi b29b8f
        {
Ankit Kumar Dwivedi ea8c72
          currGraph.node(thisNode).setAttribute(
Ankit Kumar Dwivedi ea8c72
              ORGANIZEGRAPHS_SIGN);  // Sign thisNode as part of a JSGraph
Ankit Kumar Dwivedi ea8c72
          currSequence.advance(oldNode, thisNode);
Ankit Kumar Dwivedi ea8c72
        }
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
        currSequence.m_tail = thisNode;
Ankit Kumar Dwivedi b29b8f
        currSequence.m_tailLink = currGraph.getNode(thisNode).linkOfNode(oldNode);
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
        JSGraph.newLink(i, jointsMap.find(thisNode)->second, currSequence);
Ankit Kumar Dwivedi ea8c72
      }
Ankit Kumar Dwivedi ea8c72
    }
Ankit Kumar Dwivedi ea8c72
  }
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
  // NOTE: The following may seem uncommon - you must observe that, *WHEN
Ankit Kumar Dwivedi ea8c72
  // maxThickness
Ankit Kumar Dwivedi ea8c72
  //      more isolated sequence groups may arise in the SAME SkeletonGraph; so,
Ankit Kumar Dwivedi ea8c72
  //      an organized
Ankit Kumar Dwivedi ea8c72
  //      graph may contain different unconnected basic graph-structures.
Ankit Kumar Dwivedi ea8c72
  //      Further, remaining circular sequences may still exist. Therefore:
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
  // Proceed with remaining circulars extraction
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
  _circulars : {
Ankit Kumar Dwivedi ea8c72
    // Extract all circular sequences
Ankit Kumar Dwivedi ea8c72
    // Find a sequence point
Ankit Kumar Dwivedi b29b8f
    for (i = 0; i < currGraph.getNodesCount(); ++i)
Ankit Kumar Dwivedi b29b8f
    {
Ankit Kumar Dwivedi ea8c72
      if (!currGraph.getNode(i).hasAttribute(ORGANIZEGRAPHS_SIGN) &&
Ankit Kumar Dwivedi ea8c72
          currGraph.getNode(i).degree() == 2) {
Ankit Kumar Dwivedi ea8c72
        unsigned int curr = i, currLink = 0;
Ankit Kumar Dwivedi ea8c72
        currSequence.next(curr, currLink);
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
        for (; curr != i; currSequence.next(curr, currLink))
Ankit Kumar Dwivedi ea8c72
          currGraph.node(curr).setAttribute(ORGANIZEGRAPHS_SIGN);
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
        // Add sequence
Ankit Kumar Dwivedi ea8c72
        currSequence.m_head = currSequence.m_tail = i;
Ankit Kumar Dwivedi ea8c72
        currSequence.m_headLink                   = 0;
Ankit Kumar Dwivedi ea8c72
        currSequence.m_tailLink                   = 1;
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
        globals->singleSequences.push_back(currSequence);
Ankit Kumar Dwivedi ea8c72
      }
Ankit Kumar Dwivedi ea8c72
    }
Ankit Kumar Dwivedi ea8c72
  }
Ankit Kumar Dwivedi ea8c72
  }
Ankit Kumar Dwivedi ea8c72
}
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
//==========================================================================
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72
Ankit Kumar Dwivedi ea8c72