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 } |