Example #1
0
void TrainingSetGenerator::GenerateUsingNormals(const PointCloud & input, const NormalCloud & normals, float gap) {
    Grid2Num.Resize(input.height, input.width);
    Pixel2Num.resize(input.height * input.width);

    int indexNoNan = 0;
    for (int y = 0; y < input.height; ++y) {
        for (int x = 0; x < input.width; ++x) {
            PointType point = input.at(x, y);
            NormalType normal = normals.at(x, y);
            int & num = Pixel2Num[y * input.width + x];

            if (pointHasNan(point) || pcl_isnan(normal.normal_x)) {
                num = -1;
                continue;
            }

            auto nv3f = normal.getNormalVector3fMap();
            pcl::flipNormalTowardsViewpoint(point, 0, 0, 0, nv3f[0], nv3f[1], nv3f[2]);
            nv3f *= -1;
            nv3f /= nv3f.norm();
            nv3f *= Step_ * gap;

            num = AddPoint(x, y, point, +1);

            PointType shifted(point);
            shifted.getVector3fMap() += nv3f;
            AddPoint(x, y, shifted, -1);

            indexNoNan++;
        }
    }
}
Example #2
0
	//!Shift the bitset to the left n positions
	//!Size of the bitset will not change.  If values are shifted off bitset then
	//!they will be lost.
	//!\param n Number of positions to shift the bits
	dynamic_bitset& dynamic_bitset::operator<<= (size_t n){
		//If shifting more than 32 then need to insert integer before
		size_t start(0);
		if (n>=32){
			size_t ints_to_add = n/32;
			n %=32;
			array.insert(array.begin(), ints_to_add, 0);
			array.resize(num_ints);
			if (n==0){
				return *this;
			}
		}
		
		if (n!=0){
			uint32_t shifted(lso(array[start],n));
			for(size_t i = start+1; i < num_ints ; ++i){
				shifted = lsoso(array[i], shifted, n);
			}
			
			//Clear those bits that are outside of the current scope (bits in buffer region)
			uint32_t mask = (1 << 32-buffer) - 1;
			array[num_ints-1] &= mask;
		}
		
		return *this;
	}
Example #3
0
BVValue BVValue::shift(const BVValue& _other, bool _left, bool _arithmetic) const {
	std::size_t firstSize = width() - 1;
	std::size_t highestRelevantPos = 0;

	bool fillWithOnes = !_left && _arithmetic && (*this)[width() - 1];

	while ((firstSize >>= 1) != 0)
		++highestRelevantPos;

	for (std::size_t i = highestRelevantPos + 1; i < _other.width(); ++i) {
		if (_other[i]) {
			Base allZero(width());
			return BVValue(fillWithOnes ? ~allZero : allZero);
		}
	}

	Base shifted(fillWithOnes ? ~mValue : mValue);
	std::size_t shiftBy = 1;

	for (std::size_t i = 0; i <= highestRelevantPos && i < _other.width(); ++i) {
		if (_other[i]) {
			if (_left) {
				shifted <<= shiftBy;
			} else {
				shifted >>= shiftBy;
			}
		}
		shiftBy *= 2;
	}

	return BVValue(fillWithOnes ? ~shifted : shifted);
}
Example #4
0
void UBKeyButton::paintContent(QPainter& painter)
{
    if (keybt)
    {
        QString text(QChar(shifted() ? keybt->symbol2 : keybt->symbol1));
        QRect textRect(rect().x()+2, rect().y()+2, rect().width()-4, rect().height()-4);
        painter.drawText(textRect, Qt::AlignCenter, text);
    }
}
Example #5
0
void UBKeyButton::onPress()
{
    if (keybt!=NULL)
    {
        int codeIndex = keyboard->nSpecialModifierIndex * 2 + shifted();

        if (keyboard->nSpecialModifierIndex)
        {
            if (keybt->codes[codeIndex].empty())
            {
                sendUnicodeSymbol(keyboard->specialModifier);
                sendUnicodeSymbol(keybt->codes[shifted()]);
            }
            else
            {
                sendUnicodeSymbol(keybt->codes[codeIndex]);
            }

            keyboard->nSpecialModifierIndex = 0;
        }
        else
        {
            int nSpecialModifierIndex = shifted()? keybt->modifier2 : keybt->modifier1;

            if (nSpecialModifierIndex)
            {
                keyboard->nSpecialModifierIndex = nSpecialModifierIndex;
                keyboard->specialModifier = keybt->codes[codeIndex];
            }
            else
            {
                sendUnicodeSymbol(keybt->codes[codeIndex]);            
            }
        }
    }

    if (keyboard->shift)
    {
        keyboard->shift = false;
        keyboard->update();
    }
}
Example #6
0
void special_esc(bool pressed) {
    if (pressed) {
        if (shifted() || guied()) {
            add_key(KC_GRV);
        } else {
            add_key(KC_ESC);
        }
        send_keyboard_report();
    } else {
        clear_keyboard_but_mods();
    }
}
Example #7
0
    void QuadTree::add_object(GameObject *object)
    {
        Aabb aabb = object->get_bounding_box();
        if (aabb.m_min.x < -m_radius || aabb.m_max.x > m_radius ||
            aabb.m_min.z < -m_radius || aabb.m_max.z > m_radius)
        {
            get_root()->add_object(object);
            return;
        }

        const Vector3 offset(m_radius, m_radius, m_radius);
        Aabb shifted(aabb);
        shifted.m_min += offset;
        shifted.m_max += offset;
        shifted.m_min *= m_inv_radius;
        shifted.m_max *= m_inv_radius;

        const size_t min_x = static_cast<size_t>(clamp(std::floor(shifted.m_min.x), 0.0f, 255.0f));
        const size_t min_y = static_cast<size_t>(clamp(std::floor(shifted.m_min.z), 0.0f, 255.0f));
        const size_t max_x = static_cast<size_t>(clamp(std::ceil(shifted.m_max.x), 0.0f, 255.0f));
        const size_t max_y = static_cast<size_t>(clamp(std::ceil(shifted.m_max.z), 0.0f, 255.0f));

        const size_t x_xor = (min_x ^ max_x);
//        const size_t lx = !x_xor ? 7UL : 8UL - highest_bit(x_xor);
        const size_t lx = !x_xor ? 7UL : 7UL - highest_bit(x_xor);
        const size_t y_xor = (min_y ^ max_y);
//        const size_t ly = !y_xor ? 7UL : 8UL - highest_bit(y_xor);
        const size_t ly = !y_xor ? 7UL : 7UL - highest_bit(y_xor);

        const size_t level = (lx < ly) ? lx : ly;
        const size_t x = min_x >> (8UL - level);
        const size_t y = min_y >> (8UL - level);

        QuadTreeNode &node = m_levels[level][y * (1UL << level) + x];

        DER_ASSERT( node.get_center().x - node.get_radius() <= aabb.m_min.x );
		DER_ASSERT( node.get_center().x + node.get_radius() >= aabb.m_max.x );
		DER_ASSERT( node.get_center().y - node.get_radius() <= aabb.m_min.z );
		DER_ASSERT( node.get_center().y + node.get_radius() >= aabb.m_max.z );

        m_object_node_map[object->getID()] = &node;
        node.add_object(object);
    }
Example #8
0
int main() {

    // Load images
    cv::Mat img1 = cv::imread("./output/ps0-1-a-1.png");
    std::cout << img1.type() << std::endl;
    cv::Mat img2 = cv::imread("./output/ps0-1-a-2.png");

    if (!img1.data) {
        std::cerr << "Could not open or find image 1" << std::endl;
        return -1;
    } else if (!img2.data){
        std::cerr << "Could not open or find image 2" << std::endl;
        return -1;
    }

    // Extract color channels from image 1
    std::vector<cv::Mat> channels(3);
    cv::split(img1, channels);

    // Swap channels
    cv::Mat temp(channels[0]);   // Store blue
    channels[0] = channels[2];  // Swap blue with red
    channels[2] = temp;  // Swap red with blue;

    // Save swapped image
    cv::Mat swapped1;
    cv::merge(channels, swapped1);
    cv::imwrite("./output/ps0-2-a-1.png", swapped1);

    cv::split(img1, channels);
    // Save red and img1_green channels of image 1
    cv::Mat img1_green(channels[1]);
    cv::Mat img1_red(channels[2]);
    cv::imwrite("./output/ps0-2-b-1.png", img1_green);
    cv::imwrite("./output/ps0-2-c-1.png", img1_red);

    //Take the center square region of 100x100 pixels of img1_green
    // and insert them into the center of red
    cv::Rect r(img1_green.cols / 2 - 50, img1_green.rows / 2 - 50, 100, 100);
    cv::Mat combined = img1_red, green_roi = img1_green(r);
    green_roi.copyTo(combined(cv::Rect(combined.cols/2 - 50, combined.rows/2 - 50, 100, 100)));
    cv::imwrite("./output/ps0-3-a-1.png", combined);

    // Subtract the mean from all pixels, then divide by standard deviation,
    // then multiply by 10 and add the mean back in
    cv::Mat modified, mean, stdDev;
    cv::meanStdDev(img1_green, mean, stdDev);
    cv::subtract(img1_green, mean, modified);
    cv::divide(modified, stdDev, modified);
    cv::multiply(modified, 10, modified);
    cv::add(modified, mean, modified);
    cv::imwrite("./output/ps0-4-b-1.png", modified);

    // Shift img1_green to the left by 2 pixels
    cv::Mat shifted = cv::Mat::zeros(img1_green.size(), img1_green.type());
    img1_green(cv::Rect(2, 0, img1_green.cols - 2, img1_green.rows)).copyTo(
            shifted(cv::Rect(0, 0, img1_green.cols - 2, img1_green.rows)));
    cv::imwrite("./output/ps0-4-c-1.png", shifted);

    // Subtract shifted from img1_green
    cv::Mat subtracted;
    cv::subtract(img1_green, shifted, subtracted);
    cv::imwrite("./output/ps0-4-d-1.png", subtracted);

    // Add Gaussian noise to img1's green channel
    cv::split(channels, img1);
    cv::Mat noise(img1.cols, img1.rows, img1.type());
    cv::randn(noise, 0, 5);
    cv::normalize(noise, noise, 0, 255, CV_MINMAX, img1.type());
    channels[1] += noise;
    cv::Mat green_noise;
    cv::merge(channels, green_noise);





    // display images
//    cv::imshow("Original Image 1", img1);
//    cv::imshow("Swapped Image 1", swapped1);
    cv::imshow("Green Image 1", img1_green);
//    cv::imshow("Red Image 1", img1_red);
//    cv::imshow("Combined", combined);
//    cv::imshow("Modified", modified);
//    cv::imshow("Shifted", shifted);
//    cv::imshow("Subtracted", subtracted);
    cv::imshow("Green Noise", green_noise);

//    std::string window2 = "Image 2";
//    cv::namedWindow(window2);
//    cv::imshow(window2, img2);

    cv::waitKey(0);
    return 0;
}
Example #9
0
static Keyboard::Keycode Keysym(unsigned keysym, unsigned keyflags) {
  #define pressed(keysym) (GetAsyncKeyState(keysym) & 0x8000)
  #define enabled(keysym) (GetKeyState(keysym))
  #define shifted() (pressed(VK_LSHIFT) || pressed(VK_RSHIFT))
  #define extended() (keyflags & (1 << 24))

  switch(keysym) {
  case VK_ESCAPE: return Keyboard::Keycode::Escape;
  case VK_F1: return Keyboard::Keycode::F1;
  case VK_F2: return Keyboard::Keycode::F2;
  case VK_F3: return Keyboard::Keycode::F3;
  case VK_F4: return Keyboard::Keycode::F4;
  case VK_F5: return Keyboard::Keycode::F5;
  case VK_F6: return Keyboard::Keycode::F6;
  case VK_F7: return Keyboard::Keycode::F7;
  case VK_F8: return Keyboard::Keycode::F8;
  case VK_F9: return Keyboard::Keycode::F9;
  //Keyboard::Keycode::F10 (should be captured under VK_MENU from WM_SYSKEY(UP,DOWN); but this is not working...)
  case VK_F11: return Keyboard::Keycode::F11;
  case VK_F12: return Keyboard::Keycode::F12;

  //Keyboard::Keycode::PrintScreen
  //Keyboard::Keycode::SysRq
  case VK_SCROLL: return Keyboard::Keycode::ScrollLock;
  case VK_PAUSE: return Keyboard::Keycode::Pause;
  //Keyboard::Keycode::Break

  case VK_INSERT: return extended() ? Keyboard::Keycode::Insert : Keyboard::Keycode::KeypadInsert;
  case VK_DELETE: return extended() ? Keyboard::Keycode::Delete : Keyboard::Keycode::KeypadDelete;
  case VK_HOME: return extended() ? Keyboard::Keycode::Home : Keyboard::Keycode::KeypadHome;
  case VK_END: return extended() ? Keyboard::Keycode::End : Keyboard::Keycode::KeypadEnd;
  case VK_PRIOR: return extended() ? Keyboard::Keycode::PageUp : Keyboard::Keycode::KeypadPageUp;
  case VK_NEXT: return extended() ? Keyboard::Keycode::PageDown : Keyboard::Keycode::KeypadPageDown;

  case VK_UP: return extended() ? Keyboard::Keycode::Up : Keyboard::Keycode::KeypadUp;
  case VK_DOWN: return extended() ? Keyboard::Keycode::Down : Keyboard::Keycode::KeypadDown;
  case VK_LEFT: return extended() ? Keyboard::Keycode::Left : Keyboard::Keycode::KeypadLeft;
  case VK_RIGHT: return extended() ? Keyboard::Keycode::Right : Keyboard::Keycode::KeypadRight;

  case VK_OEM_3: return !shifted() ? Keyboard::Keycode::Grave : Keyboard::Keycode::Tilde;
  case '1': return !shifted() ? Keyboard::Keycode::Number1 : Keyboard::Keycode::Exclamation;
  case '2': return !shifted() ? Keyboard::Keycode::Number2 : Keyboard::Keycode::At;
  case '3': return !shifted() ? Keyboard::Keycode::Number3 : Keyboard::Keycode::Pound;
  case '4': return !shifted() ? Keyboard::Keycode::Number4 : Keyboard::Keycode::Dollar;
  case '5': return !shifted() ? Keyboard::Keycode::Number5 : Keyboard::Keycode::Percent;
  case '6': return !shifted() ? Keyboard::Keycode::Number6 : Keyboard::Keycode::Power;
  case '7': return !shifted() ? Keyboard::Keycode::Number7 : Keyboard::Keycode::Ampersand;
  case '8': return !shifted() ? Keyboard::Keycode::Number8 : Keyboard::Keycode::Asterisk;
  case '9': return !shifted() ? Keyboard::Keycode::Number9 : Keyboard::Keycode::ParenthesisLeft;
  case '0': return !shifted() ? Keyboard::Keycode::Number0 : Keyboard::Keycode::ParenthesisRight;
  case VK_OEM_MINUS: return !shifted() ? Keyboard::Keycode::Minus : Keyboard::Keycode::Underscore;
  case VK_OEM_PLUS: return !shifted() ? Keyboard::Keycode::Equal : Keyboard::Keycode::Plus;
  case VK_BACK: return Keyboard::Keycode::Backspace;

  case VK_OEM_4: return !shifted() ? Keyboard::Keycode::BracketLeft : Keyboard::Keycode::BraceLeft;
  case VK_OEM_6: return !shifted() ? Keyboard::Keycode::BracketRight : Keyboard::Keycode::BraceRight;
  case VK_OEM_5: return !shifted() ? Keyboard::Keycode::Backslash : Keyboard::Keycode::Pipe;
  case VK_OEM_1: return !shifted() ? Keyboard::Keycode::Semicolon : Keyboard::Keycode::Colon;
  case VK_OEM_7: return !shifted() ? Keyboard::Keycode::Apostrophe : Keyboard::Keycode::Quote;
  case VK_OEM_COMMA: return !shifted() ? Keyboard::Keycode::Comma : Keyboard::Keycode::CaretLeft;
  case VK_OEM_PERIOD: return !shifted() ? Keyboard::Keycode::Period : Keyboard::Keycode::CaretRight;
  case VK_OEM_2: return !shifted() ? Keyboard::Keycode::Slash : Keyboard::Keycode::Question;

  case VK_TAB: return Keyboard::Keycode::Tab;
  case VK_CAPITAL: return Keyboard::Keycode::CapsLock;
  case VK_RETURN: return !extended() ? Keyboard::Keycode::Return : Keyboard::Keycode::Enter;
  case VK_SHIFT: return !pressed(VK_RSHIFT) ? Keyboard::Keycode::ShiftLeft : Keyboard::Keycode::ShiftRight;
  case VK_CONTROL: return !pressed(VK_RCONTROL) ? Keyboard::Keycode::ControlLeft : Keyboard::Keycode::ControlRight;
  case VK_LWIN: return Keyboard::Keycode::SuperLeft;
  case VK_RWIN: return Keyboard::Keycode::SuperRight;
  case VK_MENU:
    if(keyflags & (1 << 24)) return Keyboard::Keycode::AltRight;
    return Keyboard::Keycode::AltLeft;
  case VK_SPACE: return Keyboard::Keycode::Space;
  case VK_APPS: return Keyboard::Keycode::Menu;

  case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M':
  case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
    if(enabled(VK_CAPITAL)) {
      if(shifted()) {
        return (Keyboard::Keycode)((unsigned)Keyboard::Keycode::a + keysym - 'A');
      } else {
        return (Keyboard::Keycode)((unsigned)Keyboard::Keycode::A + keysym - 'A');
      }
    } else {
      if(shifted()) {
        return (Keyboard::Keycode)((unsigned)Keyboard::Keycode::A + keysym - 'A');
      } else {
        return (Keyboard::Keycode)((unsigned)Keyboard::Keycode::a + keysym - 'A');
      }
    }
    break;

  case VK_NUMLOCK: return Keyboard::Keycode::NumLock;
  case VK_DIVIDE: return Keyboard::Keycode::Divide;
  case VK_MULTIPLY: return Keyboard::Keycode::Multiply;
  case VK_SUBTRACT: return Keyboard::Keycode::Subtract;
  case VK_ADD: return Keyboard::Keycode::Add;
  case VK_DECIMAL: return Keyboard::Keycode::Point;
  case VK_NUMPAD1: return Keyboard::Keycode::Keypad1;
  case VK_NUMPAD2: return Keyboard::Keycode::Keypad2;
  case VK_NUMPAD3: return Keyboard::Keycode::Keypad3;
  case VK_NUMPAD4: return Keyboard::Keycode::Keypad4;
  case VK_NUMPAD5: return Keyboard::Keycode::Keypad5;
  case VK_NUMPAD6: return Keyboard::Keycode::Keypad6;
  case VK_NUMPAD7: return Keyboard::Keycode::Keypad7;
  case VK_NUMPAD8: return Keyboard::Keycode::Keypad8;
  case VK_NUMPAD9: return Keyboard::Keycode::Keypad9;
  case VK_NUMPAD0: return Keyboard::Keycode::Keypad0;

  case VK_CLEAR: return Keyboard::Keycode::KeypadCenter;
  }

  return Keyboard::Keycode::None;

  #undef pressed
  #undef enabled
  #undef shifted
  #undef extended
}
Example #10
0
Int_t  run_insert()
{

    //gDebug = 5;

    // Generate a unique RunID
    FairRunIdGenerator runID;
    UInt_t runId =  runID.generateId();

    // Create the Runtime Database ( parameter manager class )
    FairRuntimeDb* db = FairRuntimeDb::instance();

    // Set the SQL based IO as second input
    FairParTSQLIo* input_db = new FairParTSQLIo();
    input_db->SetVerbosity(1);

    // Set Global SeqNo ( Replication Global Index Base )
    //inp2->SetGlobalSeqNoIn();

    // Shutdown Mode ( True, False )
    input_db->SetShutdown(kTRUE);


    // Open first input
    input_db->open();
    db->setFirstInput(input_db);

    // Set the output=input
    db->setOutput(input_db);


    // Write a Run
    R3BDBRunInfo rInfo;
    rInfo.SetRunId(11334465);
    ValTimeStamp now;
    rInfo.SetRunTime(now);

    if (!rInfo.Commit()) cout << "-E- Error Writing Run Info " << endl;

    R3BDBRunInfo rInfo2;
    rInfo2.SetRunId(11334469);
    ValTimeStamp shifted(now.GetSec()+1,0);
    rInfo2.SetRunTime(shifted);

    if (!rInfo2.Commit()) cout << "-E- Error Writing Run Info2 " << endl;


    // Read it back in
    // make a extended query to get ConfigFileText
    ValTimeStamp tsStart(1970, 1, 1, 0, 0, 0);
    ValTimeStamp   tsEnd(2038, 1,18,19,14, 7);

    FairDbExtSqlContent extContextConfig(FairDbExtSqlContent::kStarts,tsStart,tsEnd,
                                         Detector::kLand,   // any
                                         DataType::kData); // any


    string seqSelectConfig = Form("SEQNO=%d",rInfo.GetRunId());

    FairDbReader<R3BDBRunInfo>
    rsConfig("R3BDBRUNINFO",extContextConfig,FairDb::kAnyVersion,
             seqSelectConfig.c_str());

    Int_t nConfig = rsConfig.GetNumRows();
    cout << "nConfig: = " << nConfig << endl;
    const R3BDBRunInfo* rpInfo = rsConfig.GetRow(0);

    if (rpInfo) cout << " run # " << rpInfo->GetRunId() << " has time: " << rpInfo->GetRunTime().AsString("s") << endl;

    // FairRuntimeDB deletion
    if (db) delete db;
    return 0;
}
//the call function that lets ClusterPlanarizationLayout compute a layout
//for the input using \a weight for the computation of the cluster planar subgraph
void ClusterPlanarizationLayout::call(
	Graph& G,
	ClusterGraphAttributes& acGraph,
	ClusterGraph& cGraph,
	EdgeArray<double>& edgeWeight,
	bool simpleCConnect) //default true
{
	m_nCrossings = 0;
	bool subGraph = false; // c-planar subgraph computed?

	//check some simple cases
	if (G.numberOfNodes() == 0) return;

//-------------------------------------------------------------
//we set pointers and arrays to the working graph, which can be
//the original or, in the case of non-c-planar input, a copy

	Graph* workGraph = &G;
	ClusterGraph* workCG = &cGraph;
	ClusterGraphAttributes* workACG = &acGraph;

	//potential copy of original if non c-planar
	Graph GW;
	//list of non c-planarity causing edges
	List<edge> leftEdges;

	//list of nodepairs to be connected (deleted edges)
	List<NodePair> leftWNodes;

	//store some information
	//original to copy
	NodeArray<node> resultNode(G);
	EdgeArray<edge> resultEdge(G);
	ClusterArray<cluster> resultCluster(cGraph);
	//copy to original
	NodeArray<node> orNode(G);
	EdgeArray<edge> orEdge(G);
	ClusterArray<cluster> orCluster(cGraph);

	for(node workv : G.nodes) {
		resultNode[workv] = workv; //will be set to copy if non-c-planar
		orNode[workv] = workv;
	}
	for(edge worke : G.edges) {
		resultEdge[worke] = worke; //will be set to copy if non-c-planar
		orEdge[worke] = worke;
	}
	for (cluster workc : cGraph.clusters) {
		resultCluster[workc] = workc; //will be set to copy if non-c-planar
		orCluster[workc] = workc;
	}


	//-----------------------------------------------
	//check if instance is clusterplanar and embed it
	CconnectClusterPlanarEmbed CCPE; //cccp

	bool cplanar = CCPE.embed(cGraph, G);

	List<edge> connectEdges;

	//if the graph is not c-planar, we have to check the reason and to
	//correct the problem by planarising or inserting connection edges
	if (!cplanar)
	{
		bool connect = false;

		if ( (CCPE.errCode() == CconnectClusterPlanarEmbed::nonConnected) ||
				(CCPE.errCode() == CconnectClusterPlanarEmbed::nonCConnected) )
		{
			//we insert edges to make the input c-connected
			makeCConnected(cGraph, G, connectEdges, simpleCConnect);

			//save edgearray info for inserted edges
			for(edge e : connectEdges)
			{
				resultEdge[e] = e;
				orEdge[e]     = e;
			}

			connect = true;

			CCPE.embed(cGraph, G);

			if ( (CCPE.errCode() == CconnectClusterPlanarEmbed::nonConnected) ||
				(CCPE.errCode() == CconnectClusterPlanarEmbed::nonCConnected) )
			{
				cerr << "no correct connection made\n"<<flush;
				OGDF_THROW(AlgorithmFailureException);
			}
		}//if not cconnected
		if ((CCPE.errCode() == CconnectClusterPlanarEmbed::nonPlanar) ||
			(CCPE.errCode() == CconnectClusterPlanarEmbed::nonCPlanar))
		{
			subGraph = true;
			EdgeArray<bool> inSubGraph(G, false);

			CPlanarSubClusteredGraph cps;
			if (edgeWeight.valid())
				cps.call(cGraph, inSubGraph, leftEdges, edgeWeight);
			else
				cps.call(cGraph, inSubGraph, leftEdges);
#ifdef OGDF_DEBUG
			//			for(edge worke : G.edges) {
			//				if (inSubGraph[worke])
			//					acGraph.strokeColor(worke) = "#FF0000";
			//			}
#endif
			//---------------------------------------------------------------
			//now we delete the copies of all edges not in subgraph and embed
			//the subgraph (use a new copy)

			//construct copy

			workGraph = &GW;
			workCG = new ClusterGraph(cGraph, GW, resultCluster, resultNode, resultEdge);

			//----------------------
			//reinit original arrays
			orNode.init(GW, nullptr);
			orEdge.init(GW, nullptr);
			orCluster.init(*workCG, nullptr);

			//set array entries to the appropriate values
			for (node workv : G.nodes)
				orNode[resultNode[workv]] = workv;
			for (edge worke : G.edges)
				orEdge[resultEdge[worke]] = worke;
			for (cluster workc : cGraph.clusters)
				orCluster[resultCluster[workc]] = workc;

			//----------------------------------------------------
			//create new ACG and copy values (width, height, type)

			workACG = new ClusterGraphAttributes(*workCG, workACG->attributes());
			for (node workv : GW.nodes)
			{
				//should set same attributes in construction!!!
				if (acGraph.attributes() & GraphAttributes::nodeType)
					workACG->type(workv) = acGraph.type(orNode[workv]);
				workACG->height(workv) = acGraph.height(orNode[workv]);
				workACG->width(workv) = acGraph.width(orNode[workv]);
			}
			if (acGraph.attributes() & GraphAttributes::edgeType) {
				for (edge worke : GW.edges) {
					workACG->type(worke) = acGraph.type(orEdge[worke]);
					//all other attributes are not needed or will be set
				}
			}

			for(edge ei : leftEdges)
			{
				edge e = resultEdge[ei];
				NodePair np;
				np.m_src = e->source();
				np.m_tgt = e->target();

				leftWNodes.pushBack(np);

				GW.delEdge(e);
			}

			CconnectClusterPlanarEmbed CCP;

#ifdef OGDF_DEBUG
			bool subPlanar =
#endif
				CCP.embed(*workCG, GW);
			OGDF_ASSERT(subPlanar);
		}//if not planar
		else
		{
			if (!connect)
			OGDF_THROW_PARAM(PreconditionViolatedException, pvcClusterPlanar);
		}

	}//if

	//if multiple CCs are handled, the connectedges (their copies resp.)
	//can be deleted here

	//now CCPE should give us the external face

	ClusterPlanRep CP(*workACG, *workCG);

	OGDF_ASSERT(CP.representsCombEmbedding());

	const int numCC = CP.numberOfCCs(); //equal to one
	//preliminary
	OGDF_ASSERT(numCC == 1);

	// (width,height) of the layout of each connected component
	Array<DPoint> boundingBox(numCC);

	for (int ikl = 0; ikl < numCC; ikl++)
	{

			CP.initCC(ikl);
			CP.setOriginalEmbedding();

			OGDF_ASSERT(CP.representsCombEmbedding())

			Layout drawing(CP);

			//m_planarLayouter.get().setOptions(4);//progressive

			adjEntry ae = nullptr;

			//internally compute adjEntry for outer face

			//edges that are reinserted in workGraph (in the same
			//order as leftWNodes)
			List<edge> newEdges;
			m_planarLayouter.get().call(CP, ae, drawing, leftWNodes, newEdges, *workGraph);

			OGDF_ASSERT(leftWNodes.size()==newEdges.size())
			OGDF_ASSERT(leftEdges.size()==newEdges.size())

			ListConstIterator<edge> itE = newEdges.begin();
			ListConstIterator<edge> itEor = leftEdges.begin();
			while (itE.valid())
			{
				orEdge[*itE] = *itEor;
				++itE;
				++itEor;
			}

			//hash index over cluster ids
			HashArray<int, ClusterPosition> CA;

			computeClusterPositions(CP, drawing, CA);

			// copy layout into acGraph
			// Later, we move nodes and edges in each connected component, such
			// that no two overlap.

			for(int i = CP.startNode(); i < CP.stopNode(); ++i) {
				node vG = CP.v(i);

				acGraph.x(orNode[vG]) = drawing.x(CP.copy(vG));
				acGraph.y(orNode[vG]) = drawing.y(CP.copy(vG));

				for(adjEntry adj : vG->adjEdges)
				{
					if ((adj->index() & 1) == 0) continue;
					edge eG = adj->theEdge();

					edge orE = orEdge[eG];
					if (orE)
						drawing.computePolylineClear(CP,eG,acGraph.bends(orE));
				}

			}//for

			//even assignment for all nodes is not enough, we need all clusters
			for(cluster c : workCG->clusters)
			{
				int clNumber = c->index();
				//int orNumber = originalClId[c];
				cluster orCl = orCluster[c];

				if (c != workCG->rootCluster())
				{
					OGDF_ASSERT(CA.isDefined(clNumber));
					acGraph.height(orCl) = CA[clNumber].m_height;
					acGraph.width(orCl) = CA[clNumber].m_width;
					acGraph.y(orCl) = CA[clNumber].m_miny;
					acGraph.x(orCl) = CA[clNumber].m_minx;
				}//if real cluster
			}

			// the width/height of the layout has been computed by the planar
			// layout algorithm; required as input to packing algorithm
			boundingBox[ikl] = m_planarLayouter.get().getBoundingBox();

	}//for connected components

	//postProcess(acGraph);
	//
	// arrange layouts of connected components
	//

	Array<DPoint> offset(numCC);

	m_packer.get().call(boundingBox,offset,m_pageRatio);

	// The arrangement is given by offset to the origin of the coordinate
	// system. We still have to shift each node, edge and cluster by the offset
	// of its connected component.

	const Graph::CCsInfo &ccInfo = CP.ccInfo();
	for(int i = 0; i < numCC; ++i)
	{
		const double dx = offset[i].m_x;
		const double dy = offset[i].m_y;

		HashArray<int, bool> shifted(false);

		// iterate over all nodes in ith CC
		for(int j = ccInfo.startNode(i); j < ccInfo.stopNode(i); ++j)
		{
			node v = ccInfo.v(j);

			acGraph.x(orNode[v]) += dx;
			acGraph.y(orNode[v]) += dy;

			// update cluster positions accordingly
			//int clNumber = cGraph.clusterOf(orNode[v])->index();
			cluster cl = cGraph.clusterOf(orNode[v]);

			if ((cl->index() > 0) && !shifted[cl->index()])
			{
				acGraph.y(cl) += dy;
				acGraph.x(cl) += dx;
				shifted[cl->index()] = true;
			}//if real cluster

			for(adjEntry adj : v->adjEdges) {
				if ((adj->index() & 1) == 0) continue;
				edge e = adj->theEdge();

				//edge eOr = orEdge[e];
				if (orEdge[e])
				{
					DPolyline &dpl = acGraph.bends(orEdge[e]);
					for(DPoint &p : dpl) {
						p.m_x += dx;
						p.m_y += dy;
					}
				}
			}
		}//for nodes
	}//for numcc


	while (!connectEdges.empty()) {
		G.delEdge(connectEdges.popFrontRet());
	}

	if (subGraph)
	{
		//originalClId.init();
		orCluster.init();
		orNode.init();
		orEdge.init();
		delete workCG;
		delete workACG;
	}//if subgraph created

	acGraph.removeUnnecessaryBendsHV();

}//call