|         | 
     1 #include <stdexcept> | 
|         | 
     2 #include "abstracteditmode.h" | 
|         | 
     3 #include "selectmode.h" | 
|         | 
     4 #include "drawmode.h" | 
|         | 
     5 #include "circlemode.h" | 
|         | 
     6 #include "magicwandmode.h" | 
|         | 
     7 #include "../mainWindow.h" | 
|         | 
     8  | 
|         | 
     9 AbstractEditMode::AbstractEditMode (GLRenderer* renderer) : | 
|         | 
    10 	_renderer (renderer) {} | 
|         | 
    11  | 
|         | 
    12 AbstractEditMode* AbstractEditMode::createByType (GLRenderer* renderer, EditModeType type) | 
|         | 
    13 { | 
|         | 
    14 	switch (type) | 
|         | 
    15 	{ | 
|         | 
    16 		case EditModeType::Select: return new SelectMode (renderer); | 
|         | 
    17 		case EditModeType::Draw: return new DrawMode (renderer); | 
|         | 
    18 		case EditModeType::Circle: return new CircleMode (renderer); | 
|         | 
    19 		case EditModeType::MagicWand: return new MagicWandMode (renderer); | 
|         | 
    20 	} | 
|         | 
    21  | 
|         | 
    22 	throw std::logic_error ("bad type given to AbstractEditMode::createByType"); | 
|         | 
    23 } | 
|         | 
    24  | 
|         | 
    25 GLRenderer* AbstractEditMode::renderer() const | 
|         | 
    26 { | 
|         | 
    27 	return _renderer; | 
|         | 
    28 } | 
|         | 
    29  | 
|         | 
    30 AbstractDrawMode::AbstractDrawMode (GLRenderer* renderer) : | 
|         | 
    31 	AbstractEditMode (renderer), | 
|         | 
    32 	_polybrush (QBrush (QColor (64, 192, 0, 128))) | 
|         | 
    33 { | 
|         | 
    34 	// Disable the context menu - we need the right mouse button | 
|         | 
    35 	// for removing vertices. | 
|         | 
    36 	renderer->setContextMenuPolicy (Qt::NoContextMenu); | 
|         | 
    37  | 
|         | 
    38 	// Use the crosshair cursor when drawing. | 
|         | 
    39 	renderer->setCursor (Qt::CrossCursor); | 
|         | 
    40  | 
|         | 
    41 	// Clear the selection when beginning to draw. | 
|         | 
    42 	getCurrentDocument()->clearSelection(); | 
|         | 
    43  | 
|         | 
    44 	g_win->updateSelection(); | 
|         | 
    45 	m_drawedVerts.clear(); | 
|         | 
    46 } | 
|         | 
    47  | 
|         | 
    48 AbstractSelectMode::AbstractSelectMode (GLRenderer* renderer) : | 
|         | 
    49 	AbstractEditMode (renderer) | 
|         | 
    50 { | 
|         | 
    51 	renderer->unsetCursor(); | 
|         | 
    52 	renderer->setContextMenuPolicy (Qt::DefaultContextMenu); | 
|         | 
    53 } | 
|         | 
    54  | 
|         | 
    55 // ============================================================================= | 
|         | 
    56 // | 
|         | 
    57 void AbstractDrawMode::addDrawnVertex (Vertex const& pos) | 
|         | 
    58 { | 
|         | 
    59 	if (preAddVertex (pos)) | 
|         | 
    60 		return; | 
|         | 
    61  | 
|         | 
    62 	m_drawedVerts << pos; | 
|         | 
    63 } | 
|         | 
    64  | 
|         | 
    65 virtual void AbstractDrawMode::mouseReleased (MouseEventData const& data) | 
|         | 
    66 { | 
|         | 
    67 	if (data.releasedButtons & Qt::MidButton) | 
|         | 
    68 	{ | 
|         | 
    69 		// Find the closest vertex to our cursor | 
|         | 
    70 		double			minimumDistance = 1024.0; | 
|         | 
    71 		const Vertex*	closest = null; | 
|         | 
    72 		Vertex			cursorPosition = renderer()->coordconv2_3 (data.ev->pos(), false); | 
|         | 
    73 		QPoint			cursorPosition2D (data.ev->pos()); | 
|         | 
    74 		const Axis		relZ = renderer()->getRelativeZ(); | 
|         | 
    75 		QList<Vertex>	vertices; | 
|         | 
    76  | 
|         | 
    77 		for (auto it = renderer()->document()->vertices().begin(); it != renderer()->document()->vertices().end(); ++it) | 
|         | 
    78 			vertices << it.key(); | 
|         | 
    79  | 
|         | 
    80 		// Sort the vertices in order of distance to camera | 
|         | 
    81 		std::sort (vertices.begin(), vertices.end(), [&](const Vertex& a, const Vertex& b) -> bool | 
|         | 
    82 		{ | 
|         | 
    83 			if (renderer()->getFixedCamera (renderer()->camera()).negatedDepth) | 
|         | 
    84 				return a[relZ] > b[relZ]; | 
|         | 
    85  | 
|         | 
    86 			return a[relZ] < b[relZ]; | 
|         | 
    87 		}); | 
|         | 
    88  | 
|         | 
    89 		for (const Vertex& vrt : vertices) | 
|         | 
    90 		{ | 
|         | 
    91 			// If the vertex in 2d space is very close to the cursor then we use | 
|         | 
    92 			// it regardless of depth. | 
|         | 
    93 			QPoint vect2d = renderer()->coordconv3_2 (vrt) - cursorPosition2D; | 
|         | 
    94 			const double distance2DSquared = std::pow (vect2d.x(), 2) + std::pow (vect2d.y(), 2); | 
|         | 
    95 			if (distance2DSquared < 16.0 * 16.0) | 
|         | 
    96 			{ | 
|         | 
    97 				closest = &vrt; | 
|         | 
    98 				break; | 
|         | 
    99 			} | 
|         | 
   100  | 
|         | 
   101 			// Check if too far away from the cursor. | 
|         | 
   102 			if (distance2DSquared > 64.0 * 64.0) | 
|         | 
   103 				continue; | 
|         | 
   104  | 
|         | 
   105 			// Not very close to the cursor. Compare using true distance, | 
|         | 
   106 			// including depth. | 
|         | 
   107 			const double distanceSquared = (vrt - cursorPosition).lengthSquared(); | 
|         | 
   108  | 
|         | 
   109 			if (distanceSquared < minimumDistance) | 
|         | 
   110 			{ | 
|         | 
   111 				minimumDistance = distanceSquared; | 
|         | 
   112 				closest = &vrt; | 
|         | 
   113 			} | 
|         | 
   114 		} | 
|         | 
   115  | 
|         | 
   116 		if (closest != null) | 
|         | 
   117 			addDrawnVertex (*closest); | 
|         | 
   118  | 
|         | 
   119 		return true; | 
|         | 
   120 	} | 
|         | 
   121  | 
|         | 
   122 	return false; | 
|         | 
   123 } |