| 114 obj->replace (newobj); |
114 obj->replace (newobj); |
| 115 } |
115 } |
| 116 |
116 |
| 117 void AlgorithmToolset::makeBorders() |
117 void AlgorithmToolset::makeBorders() |
| 118 { |
118 { |
| 119 int num = 0; |
119 int count = 0; |
| 120 |
120 |
| 121 for (LDObject* obj : selectedObjects()) |
121 for (LDObject* object : selectedObjects()) |
| 122 { |
122 { |
| 123 const LDObjectType type = obj->type(); |
123 const LDObjectType type = object->type(); |
| 124 |
124 |
| 125 if (type != OBJ_Quad and type != OBJ_Triangle) |
125 if (type != OBJ_Quad and type != OBJ_Triangle) |
| 126 continue; |
126 continue; |
| 127 |
127 |
| 128 LDLine* lines[4]; |
128 Model lines; |
| 129 |
129 |
| 130 if (type == OBJ_Quad) |
130 if (type == OBJ_Quad) |
| 131 { |
131 { |
| 132 LDQuad* quad = static_cast<LDQuad*> (obj); |
132 LDQuad* quad = static_cast<LDQuad*>(object); |
| 133 lines[0] = LDSpawn<LDLine> (quad->vertex (0), quad->vertex (1)); |
133 lines.emplace<LDLine>(quad->vertex (0), quad->vertex (1)); |
| 134 lines[1] = LDSpawn<LDLine> (quad->vertex (1), quad->vertex (2)); |
134 lines.emplace<LDLine>(quad->vertex (1), quad->vertex (2)); |
| 135 lines[2] = LDSpawn<LDLine> (quad->vertex (2), quad->vertex (3)); |
135 lines.emplace<LDLine>(quad->vertex (2), quad->vertex (3)); |
| 136 lines[3] = LDSpawn<LDLine> (quad->vertex (3), quad->vertex (0)); |
136 lines.emplace<LDLine>(quad->vertex (3), quad->vertex (0)); |
| 137 } |
137 } |
| 138 else |
138 else |
| 139 { |
139 { |
| 140 LDTriangle* tri = static_cast<LDTriangle*> (obj); |
140 LDTriangle* triangle = static_cast<LDTriangle*>(object); |
| 141 lines[0] = LDSpawn<LDLine> (tri->vertex (0), tri->vertex (1)); |
141 lines.emplace<LDLine>(triangle->vertex (0), triangle->vertex (1)); |
| 142 lines[1] = LDSpawn<LDLine> (tri->vertex (1), tri->vertex (2)); |
142 lines.emplace<LDLine>(triangle->vertex (1), triangle->vertex (2)); |
| 143 lines[2] = LDSpawn<LDLine> (tri->vertex (2), tri->vertex (0)); |
143 lines.emplace<LDLine>(triangle->vertex (2), triangle->vertex (0)); |
| 144 lines[3] = nullptr; |
144 } |
| 145 } |
145 |
| 146 |
146 count += countof(lines.objects()); |
| 147 for (int i = 0; i < countof (lines); ++i) |
147 currentDocument()->merge(lines, object->lineNumber() + 1); |
| 148 { |
148 } |
| 149 if (lines[i] == nullptr) |
149 |
| 150 continue; |
150 print(tr("Added %1 border lines"), count); |
| 151 |
|
| 152 long idx = obj->lineNumber() + i + 1; |
|
| 153 currentDocument()->insertObject (idx, lines[i]); |
|
| 154 ++num; |
|
| 155 } |
|
| 156 } |
|
| 157 |
|
| 158 print (tr ("Added %1 border lines"), num); |
|
| 159 } |
151 } |
| 160 |
152 |
| 161 void AlgorithmToolset::roundCoordinates() |
153 void AlgorithmToolset::roundCoordinates() |
| 162 { |
154 { |
| 163 setlocale (LC_ALL, "C"); |
155 setlocale (LC_ALL, "C"); |
| 388 } |
380 } |
| 389 |
381 |
| 390 void AlgorithmToolset::splitLines() |
382 void AlgorithmToolset::splitLines() |
| 391 { |
383 { |
| 392 bool ok; |
384 bool ok; |
| 393 int segments = QInputDialog::getInt (m_window, APPNAME, "Amount of segments:", |
385 int numSegments = QInputDialog::getInt (m_window, APPNAME, "Amount of segments:", |
| 394 m_config->splitLinesSegments(), 0, std::numeric_limits<int>::max(), 1, &ok); |
386 m_config->splitLinesSegments(), 0, std::numeric_limits<int>::max(), 1, &ok); |
| 395 |
387 |
| 396 if (not ok) |
388 if (not ok) |
| 397 return; |
389 return; |
| 398 |
390 |
| 399 m_config->setSplitLinesSegments (segments); |
391 m_config->setSplitLinesSegments (numSegments); |
| 400 |
392 |
| 401 for (LDObject* obj : selectedObjects()) |
393 for (LDObject* obj : selectedObjects()) |
| 402 { |
394 { |
| 403 if (not isOneOf (obj->type(), OBJ_Line, OBJ_CondLine)) |
395 if (not isOneOf (obj->type(), OBJ_Line, OBJ_CondLine)) |
| 404 continue; |
396 continue; |
| 405 |
397 |
| 406 QVector<LDObject*> newsegs; |
398 Model segments; |
| 407 |
399 |
| 408 for (int i = 0; i < segments; ++i) |
400 for (int i = 0; i < numSegments; ++i) |
| 409 { |
401 { |
| 410 LDObject* segment; |
402 Vertex v0; |
| 411 Vertex v0, v1; |
403 Vertex v1; |
| 412 |
404 |
| 413 v0.apply ([&](Axis ax, double& a) |
405 v0.apply ([&](Axis ax, double& a) |
| 414 { |
406 { |
| 415 double len = obj->vertex (1)[ax] - obj->vertex (0)[ax]; |
407 double len = obj->vertex (1)[ax] - obj->vertex (0)[ax]; |
| 416 a = (obj->vertex (0)[ax] + ((len * i) / segments)); |
408 a = (obj->vertex (0)[ax] + ((len * i) / numSegments)); |
| 417 }); |
409 }); |
| 418 |
410 |
| 419 v1.apply ([&](Axis ax, double& a) |
411 v1.apply ([&](Axis ax, double& a) |
| 420 { |
412 { |
| 421 double len = obj->vertex (1)[ax] - obj->vertex (0)[ax]; |
413 double len = obj->vertex (1)[ax] - obj->vertex (0)[ax]; |
| 422 a = (obj->vertex (0)[ax] + ((len * (i + 1)) / segments)); |
414 a = (obj->vertex (0)[ax] + ((len * (i + 1)) / numSegments)); |
| 423 }); |
415 }); |
| 424 |
416 |
| 425 if (obj->type() == OBJ_Line) |
417 if (obj->type() == OBJ_Line) |
| 426 segment = LDSpawn<LDLine> (v0, v1); |
418 segments.emplace<LDLine>(v0, v1); |
| 427 else |
419 else |
| 428 segment = LDSpawn<LDCondLine> (v0, v1, obj->vertex (2), obj->vertex (3)); |
420 segments.emplace<LDCondLine>(v0, v1, obj->vertex (2), obj->vertex (3)); |
| 429 |
421 } |
| 430 newsegs << segment; |
422 |
| 431 } |
423 currentDocument()->replace(obj, segments); |
| 432 |
|
| 433 int ln = obj->lineNumber(); |
|
| 434 |
|
| 435 for (LDObject* seg : newsegs) |
|
| 436 currentDocument()->insertObject (ln++, seg); |
|
| 437 |
|
| 438 currentDocument()->remove(obj); |
|
| 439 } |
424 } |
| 440 |
425 |
| 441 m_window->buildObjectList(); |
426 m_window->buildObjectList(); |
| 442 m_window->refresh(); |
427 m_window->refresh(); |
| 443 } |
428 } |
| 543 bfctype = it->statement(); |
528 bfctype = it->statement(); |
| 544 break; |
529 break; |
| 545 } |
530 } |
| 546 } |
531 } |
| 547 |
532 |
| 548 // Get the body of the document in LDraw code |
|
| 549 for (LDObject* obj : selectedObjects()) |
|
| 550 code << obj->asText(); |
|
| 551 |
|
| 552 // Create the new subfile document |
533 // Create the new subfile document |
| 553 LDDocument* doc = m_window->newDocument(); |
534 LDDocument* subfile = m_window->newDocument(); |
| 554 doc->openForEditing(); |
535 subfile->openForEditing(); |
| 555 doc->setFullPath (fullsubname); |
536 subfile->setFullPath(fullsubname); |
| 556 doc->setName (LDDocument::shortenName (fullsubname)); |
537 subfile->setName(LDDocument::shortenName(fullsubname)); |
| 557 |
538 |
| 558 LDObjectList objs; |
539 Model header; |
| 559 objs << LDSpawn<LDComment> (subtitle); |
540 header.emplace<LDComment>(subtitle); |
| 560 objs << LDSpawn<LDComment> ("Name: "); // This gets filled in when the subfile is saved |
541 header.emplace<LDComment>("Name: "); // This gets filled in when the subfile is saved |
| 561 objs << LDSpawn<LDComment> (format ("Author: %1 [%2]", m_config->defaultName(), m_config->defaultUser())); |
542 header.emplace<LDComment>(format("Author: %1 [%2]", m_config->defaultName(), m_config->defaultUser())); |
| 562 objs << LDSpawn<LDComment> ("!LDRAW_ORG Unofficial_Subpart"); |
543 header.emplace<LDComment>("!LDRAW_ORG Unofficial_Subpart"); |
| 563 |
544 |
| 564 if (not license.isEmpty()) |
545 if (not license.isEmpty()) |
| 565 objs << LDSpawn<LDComment> (license); |
546 header.emplace<LDComment>(license); |
| 566 |
547 |
| 567 objs << LDSpawn<LDEmpty>(); |
548 header.emplace<LDEmpty>(); |
| 568 objs << LDSpawn<LDBfc> (bfctype); |
549 header.emplace<LDBfc>(bfctype); |
| 569 objs << LDSpawn<LDEmpty>(); |
550 header.emplace<LDEmpty>(); |
| 570 |
551 subfile->merge(header); |
| 571 doc->addObjects (objs); |
552 |
| 572 |
553 // Copy the body over to the new document |
| 573 // Add the actual subfile code to the new document |
554 for (LDObject* object : selectedObjects()) |
| 574 for (QString line : code) |
555 subfile->addObject(object->createCopy()); |
| 575 { |
|
| 576 LDObject* obj = ParseLine (line); |
|
| 577 doc->addObject (obj); |
|
| 578 } |
|
| 579 |
556 |
| 580 // Try save it |
557 // Try save it |
| 581 if (m_window->save (doc, true)) |
558 if (m_window->save(subfile, true)) |
| 582 { |
559 { |
| 583 // Save was successful. Delete the original selection now from the |
560 // Save was successful. Delete the original selection now from the |
| 584 // main document. |
561 // main document. |
| 585 for (LDObject* object : selectedObjects()) |
562 for (LDObject* object : selectedObjects().toList()) |
| 586 currentDocument()->remove(object); |
563 currentDocument()->remove(object); |
| 587 |
564 |
| 588 // Add a reference to the new subfile to where the selection was |
565 // Add a reference to the new subfile to where the selection was |
| 589 LDSubfileReference* ref = LDSpawn<LDSubfileReference>(); |
566 currentDocument()->emplaceAt<LDSubfileReference>(referencePosition, subfile, Matrix::identity, Origin); |
| 590 ref->setColor (MainColor); |
|
| 591 ref->setFileInfo (doc); |
|
| 592 ref->setPosition (Origin); |
|
| 593 ref->setTransformationMatrix (Matrix::identity); |
|
| 594 currentDocument()->insertObject (refidx, ref); |
|
| 595 |
567 |
| 596 // Refresh stuff |
568 // Refresh stuff |
| 597 m_window->updateDocumentList(); |
569 m_window->updateDocumentList(); |
| 598 m_window->doFullRefresh(); |
570 m_window->doFullRefresh(); |
| 599 } |
571 } |
| 600 else |
572 else |
| 601 { |
573 { |
| 602 // Failed to save. |
574 // Failed to save. |
| 603 doc->close(); |
575 subfile->close(); |
| 604 } |
576 } |
| 605 } |
577 } |