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); |
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; |