src/gldraw.cpp

changeset 500
cad8cdc42a64
parent 499
ebd30d9eb667
child 501
8f314f3f5054
equal deleted inserted replaced
499:ebd30d9eb667 500:cad8cdc42a64
34 #include "misc.h" 34 #include "misc.h"
35 #include "history.h" 35 #include "history.h"
36 #include "dialogs.h" 36 #include "dialogs.h"
37 #include "addObjectDialog.h" 37 #include "addObjectDialog.h"
38 #include "messagelog.h" 38 #include "messagelog.h"
39 #include "primitives.h"
39 #include "moc_gldraw.cpp" 40 #include "moc_gldraw.cpp"
40 41
41 static const LDFixedCameraInfo g_FixedCameras[6] = 42 static const LDFixedCameraInfo g_FixedCameras[6] =
42 { {{ 1, 0, 0 }, X, Z, false, false }, 43 { {{ 1, 0, 0 }, X, Z, false, false },
43 {{ 0, 0, 0 }, X, Y, false, true }, 44 {{ 0, 0, 0 }, X, Y, false, true },
653 // Same for the outer ring. Note that the indices are offset by 1 654 // Same for the outer ring. Note that the indices are offset by 1
654 // because of the insertion done above bumps the values. 655 // because of the insertion done above bumps the values.
655 if (points.size() >= 33) 656 if (points.size() >= 33)
656 points.insert (33, points[17]); 657 points.insert (33, points[17]);
657 658
659 // Draw the circle/ring
660 paint.setPen (linepen);
661 paint.setBrush ((m_drawedVerts.size() >= 2) ? polybrush : Qt::NoBrush);
662 paint.drawPolygon (QPolygon (points));
663
658 { // Draw the current radius in the middle of the circle. 664 { // Draw the current radius in the middle of the circle.
659 QPoint origin = coordconv3_2 (m_drawedVerts[0]); 665 QPoint origin = coordconv3_2 (m_drawedVerts[0]);
660 str label = str::number (dist0); 666 str label = str::number (dist0);
661 paint.setPen (textpen); 667 paint.setPen (textpen);
662 paint.drawText (origin.x() - (metrics.width (label) / 2), origin.y(), label); 668 paint.drawText (origin.x() - (metrics.width (label) / 2), origin.y(), label);
664 if (m_drawedVerts.size() >= 2) 670 if (m_drawedVerts.size() >= 2)
665 { label = str::number (dist1); 671 { label = str::number (dist1);
666 paint.drawText (origin.x() - (metrics.width (label) / 2), origin.y() + metrics.height(), label); 672 paint.drawText (origin.x() - (metrics.width (label) / 2), origin.y() + metrics.height(), label);
667 } 673 }
668 } 674 }
669
670 // Draw the circle/ring
671 paint.setPen (linepen);
672 paint.setBrush ((m_drawedVerts.size() >= 2) ? polybrush : Qt::NoBrush);
673 paint.drawPolygon (QPolygon (points));
674 } 675 }
675 } 676 }
676 } 677 }
677 678
678 // Camera icons 679 // Camera icons
892 893
893 // ============================================================================= 894 // =============================================================================
894 // ----------------------------------------------------------------------------- 895 // -----------------------------------------------------------------------------
895 void GLRenderer::addDrawnVertex (vertex pos) 896 void GLRenderer::addDrawnVertex (vertex pos)
896 { // If we picked an already-existing vertex, stop drawing 897 { // If we picked an already-existing vertex, stop drawing
897 for (vertex & vert : m_drawedVerts) 898 if (editMode() != CircleMode)
898 { if (vert == pos) 899 { for (vertex& vert : m_drawedVerts)
899 { endDraw (true); 900 { if (vert == pos)
900 return; 901 { endDraw (true);
902 return;
903 }
901 } 904 }
902 } 905 }
903 906
904 m_drawedVerts << pos; 907 m_drawedVerts << pos;
905 } 908 }
1324 void GLRenderer::endDraw (bool accept) 1327 void GLRenderer::endDraw (bool accept)
1325 { (void) accept; 1328 { (void) accept;
1326 1329
1327 // Clean the selection and create the object 1330 // Clean the selection and create the object
1328 List<vertex>& verts = m_drawedVerts; 1331 List<vertex>& verts = m_drawedVerts;
1329 LDObject* obj = null; 1332 List<LDObject*> objs;
1330 1333
1331 switch (editMode()) 1334 switch (editMode())
1332 { case Draw: 1335 { case Draw:
1333 1336 { if (m_rectdraw)
1334 if (m_rectdraw)
1335 { LDQuad* quad = new LDQuad; 1337 { LDQuad* quad = new LDQuad;
1336 1338
1337 // Copy the vertices from m_rectverts 1339 // Copy the vertices from m_rectverts
1338 updateRectVerts(); 1340 updateRectVerts();
1339 1341
1340 for (int i = 0; i < quad->vertices(); ++i) 1342 for (int i = 0; i < quad->vertices(); ++i)
1341 quad->setVertex (i, m_rectverts[i]); 1343 quad->setVertex (i, m_rectverts[i]);
1342 1344
1343 quad->setColor (maincolor); 1345 quad->setColor (maincolor);
1344 obj = quad; 1346 objs << quad;
1345 } 1347 }
1346 else 1348 else
1347 { switch (verts.size()) 1349 { switch (verts.size())
1348 { case 1: 1350 { case 1:
1349 // 1 vertex - add a vertex object 1351 { // 1 vertex - add a vertex object
1350 obj = new LDVertex; 1352 LDVertex* obj = new LDVertex;
1351 static_cast<LDVertex*> (obj)->pos = verts[0]; 1353 obj->pos = verts[0];
1352 obj->setColor (maincolor); 1354 obj->setColor (maincolor);
1353 break; 1355 objs << obj;
1356 } break;
1354 1357
1355 case 2: 1358 case 2:
1356 // 2 verts - make a line 1359 { // 2 verts - make a line
1357 obj = new LDLine (verts[0], verts[1]); 1360 LDLine* obj = new LDLine (verts[0], verts[1]);
1358 obj->setColor (edgecolor); 1361 obj->setColor (edgecolor);
1359 break; 1362 objs << obj;
1363 } break;
1360 1364
1361 case 3: 1365 case 3:
1362 case 4: 1366 case 4:
1363 obj = (verts.size() == 3) ? 1367 { LDObject* obj = (verts.size() == 3) ?
1364 static_cast<LDObject*> (new LDTriangle) : 1368 static_cast<LDObject*> (new LDTriangle) :
1365 static_cast<LDObject*> (new LDQuad); 1369 static_cast<LDObject*> (new LDQuad);
1366 1370
1367 obj->setColor (maincolor); 1371 obj->setColor (maincolor);
1368 1372
1369 for (int i = 0; i < obj->vertices(); ++i) 1373 for (int i = 0; i < obj->vertices(); ++i)
1370 obj->setVertex (i, verts[i]); 1374 obj->setVertex (i, verts[i]);
1371 1375
1372 break; 1376 objs << obj;
1377 } break;
1373 } 1378 }
1374 } 1379 }
1375 1380 } break;
1376 break;
1377 1381
1378 case CircleMode: 1382 case CircleMode:
1379 { const double dist = circleDrawDist (0); 1383 { const int segs = lores, divs = lores; // TODO: make customizable
1380 1384 double dist0 = circleDrawDist (0),
1381 matrix transform = g_circleDrawTransforms[camera() % 3]; 1385 dist1 = circleDrawDist (1);
1382 1386 enum {Circle, Ring, Disc, CustomRing} type = Ring;
1383 for (int i = 0; i < 9; ++i) 1387 int num = 0;
1384 { if (transform[i] == 2) 1388 double scale;
1385 transform[i] = dist; 1389
1386 elif (transform[i] == 1 && camera() >= 3) 1390 if (dist1 < dist0)
1387 transform[i] = -1; 1391 std::swap<double> (dist0, dist1);
1392
1393 if (dist0 == dist1)
1394 { scale = dist0;
1395 type = Circle;
1396 } elif (dist0 == 0 || dist1 == 0)
1397 { scale = (dist0 != 0) ? dist0 : dist1;
1398 type = Disc;
1399 } else
1400 { /* scale = |r1 - r0|
1401 number = r0 / scale */
1402 scale = abs (dist1 - dist0);
1403 assert (scale != 0);
1404
1405 if (!isInteger (dist0) || !isInteger (scale) || (((int) dist0) % ((int) scale)) != 0)
1406 type = CustomRing; // Non-integer ring number - make a custom ring
1407 else
1408 num = ((int) dist0) / ((int) scale);
1388 } 1409 }
1389 1410
1390 LDSubfile* ref = new LDSubfile; 1411 if (type == CustomRing)
1391 ref->setFileInfo (findLoadedFile ("4-4edge.dat")); 1412 { // Last resort: draw the ring with quads
1392 ref->setTransform (transform); 1413 List<QLineF> c0, c1;
1393 ref->setPosition (m_drawedVerts[0]); 1414
1394 ref->setColor (maincolor); 1415 makeCircle (segs, divs, dist0, c0);
1395 obj = ref; 1416 makeCircle (segs, divs, dist1, c1);
1396 } 1417
1397 break; 1418 for (int i = 0; i < 16; ++i)
1419 {
1420 }
1421 }
1422 else
1423 { matrix transform = g_circleDrawTransforms[camera() % 3];
1424 LDFile* refFile = null;
1425
1426 for (int i = 0; i < 9; ++i)
1427 { if (transform[i] == 2)
1428 transform[i] = scale;
1429 elif (transform[i] == 1 && camera() >= 3)
1430 transform[i] = -1;
1431 }
1432
1433 switch (type)
1434 { case Circle:
1435 { refFile = getFile ("4-4edge.dat");
1436 } break;
1437
1438 case Disc:
1439 { refFile = getFile ("4-4disc.dat");
1440 } break;
1441
1442 case Ring:
1443 { if ((refFile = getFile (radialFileName (::Ring, lores, lores, num))) == null)
1444 { refFile = generatePrimitive (::Ring, lores, lores, num);
1445 refFile->setImplicit (false);
1446 }
1447 } break;
1448 }
1449
1450 if (refFile)
1451 { LDSubfile* ref = new LDSubfile;
1452 ref->setFileInfo (refFile);
1453 ref->setTransform (transform);
1454 ref->setPosition (m_drawedVerts[0]);
1455 ref->setColor (maincolor);
1456 objs << ref;
1457 }
1458 }
1459 } break;
1398 1460
1399 case Select: 1461 case Select:
1400 assert (false); 1462 { assert (false);
1401 return; 1463 return;
1402 } 1464 } break;
1403 1465 }
1404 if (obj) 1466
1467 if (objs.size() > 0)
1405 { g_win->beginAction (null); 1468 { g_win->beginAction (null);
1406 file()->addObject (obj); 1469
1407 compileObject (obj); 1470 for (LDObject* obj : objs)
1408 g_win->fullRefresh(); 1471 { file()->addObject (obj);
1472 compileObject (obj);
1473 }
1474
1475 g_win->refresh();
1409 g_win->endAction(); 1476 g_win->endAction();
1410 } 1477 }
1411 1478
1412 m_drawedVerts.clear(); 1479 m_drawedVerts.clear();
1413 m_rectdraw = false; 1480 m_rectdraw = false;

mercurial