@@ -62,11 +62,11 @@ bool operator==(const ContourKey& key1, const ContourKey& key2)
6262 * @param mesh The mesh to fill the voxels grid with
6363 * @param texture_data_provider The provider containing the painted texture data
6464 * @param voxel_grid The voxels grid to be filled with mesh data
65- * @param main_extruder The main extruder of the mesh, to be used when we find a texture part that uses a disabled/inexisting extruder
65+ * @param mesh_extruder_nr The main mesh extruder number
6666 * @return True if this generated relevant data for multi-extruder, otherwise this means the mesh is completely filled with only extruder 0 and there is no need to go further on
6767 * trying to calculate the modified meshes.
6868 */
69- bool makeVoxelGridFromTexture (const Mesh& mesh, const std::shared_ptr<TextureDataProvider>& texture_data_provider, VoxelGrid& voxel_grid, const size_t main_extruder )
69+ bool makeVoxelGridFromTexture (const Mesh& mesh, const std::shared_ptr<TextureDataProvider>& texture_data_provider, VoxelGrid& voxel_grid, const uint8_t mesh_extruder_nr )
7070{
7171 boost::concurrent_flat_set<uint8_t > found_extruders;
7272 std::unordered_set<size_t > active_extruders;
@@ -112,7 +112,7 @@ bool makeVoxelGridFromTexture(const Mesh& mesh, const std::shared_ptr<TextureDat
112112 std::optional<uint32_t > extruder_nr = texture_data_provider->getValue (std::get<0 >(pixel), std::get<1 >(pixel), " extruder" );
113113 if (! extruder_nr.has_value () || ! active_extruders.contains (extruder_nr.value ()))
114114 {
115- extruder_nr = main_extruder ;
115+ extruder_nr = mesh_extruder_nr ;
116116 }
117117
118118 voxel_grid.setOrUpdateOccupation (traversed_voxel, extruder_nr.value ());
@@ -122,14 +122,14 @@ bool makeVoxelGridFromTexture(const Mesh& mesh, const std::shared_ptr<TextureDat
122122
123123 if (found_extruders.size () == 1 )
124124 {
125- // We have found only one extruder in the texture, so return true only if this extruder is not 0 , otherwise the rest is useless
126- bool is_non_zero = true ;
125+ // We have found only one extruder in the texture, so return true only if this extruder is not the mesh extruder , otherwise the rest is useless
126+ bool is_specific_extruder = true ;
127127 found_extruders.visit_all (
128- [&is_non_zero ](const uint8_t extruder_nr)
128+ [&is_specific_extruder, &mesh_extruder_nr ](const uint8_t extruder_nr)
129129 {
130- is_non_zero = extruder_nr != 0 ;
130+ is_specific_extruder = extruder_nr != mesh_extruder_nr ;
131131 });
132- return is_non_zero ;
132+ return is_specific_extruder ;
133133 }
134134
135135 return true ;
@@ -138,22 +138,23 @@ bool makeVoxelGridFromTexture(const Mesh& mesh, const std::shared_ptr<TextureDat
138138/* !
139139 * Create modifier meshes from the given voxels grid, filled with the contours of the areas that should be processed by the different extruders.
140140 * @param voxel_grid The voxels grid containing the extruder occupations
141+ * @param mesh_extruder_nr The main mesh extruder number
141142 * @return A list of modifier meshes to be registered
142143 *
143144 * This function works by treating each horizontal plane separately of the voxels grid. For each plane, we apply a marching squares algorithm in order to generate 2D polygons.
144145 * Then we just have to extrude those polygons vertically. The final mesh has no horizontal face, thus it is not watertight at all. However, since it will subsequently
145146 * be re-sliced on XY planes, this is good enough.
146147 */
147- std::vector<Mesh> makeMeshesFromVoxelsGrid (const VoxelGrid& voxel_grid)
148+ std::vector<Mesh> makeMeshesFromVoxelsGrid (const VoxelGrid& voxel_grid, const uint8_t mesh_extruder_nr )
148149{
149150 spdlog::debug (" Make modifier meshes from voxels grid" );
150151
151- // First, gather all positions that should be considered for the marching square, e.g. all that have a non-null extruder and around them
152+ // First, gather all positions that should be considered for the marching square, e.g. all that have a specific extruder and around them
152153 boost::concurrent_flat_set<VoxelGrid::LocalCoordinates> marching_squares;
153154 voxel_grid.visitOccupiedVoxels (
154- [&marching_squares](const auto & occupied_voxel)
155+ [&marching_squares, &mesh_extruder_nr ](const auto & occupied_voxel)
155156 {
156- if (occupied_voxel.second > 0 )
157+ if (occupied_voxel.second != mesh_extruder_nr )
157158 {
158159 marching_squares.insert (occupied_voxel.first );
159160 if (occupied_voxel.first .position .x > 0 )
@@ -206,25 +207,28 @@ std::vector<Mesh> makeMeshesFromVoxelsGrid(const VoxelGrid& voxel_grid)
206207#ifdef __cpp_lib_execution
207208 std::execution::par,
208209#endif
209- [&voxel_grid, &raw_contours, &position_delta_center, &marching_segments](const VoxelGrid::LocalCoordinates square_start)
210+ [&voxel_grid, &raw_contours, &position_delta_center, &marching_segments, &mesh_extruder_nr ](const VoxelGrid::LocalCoordinates square_start)
210211 {
211212 const int32_t x_plus1 = static_cast <int32_t >(square_start.position .x ) + 1 ;
212213 const bool x_plus1_valid = x_plus1 <= std::numeric_limits<uint16_t >::max ();
213214 const int32_t y_plus1 = static_cast <int32_t >(square_start.position .y ) + 1 ;
214215 const bool y_plus1_valid = y_plus1 <= std::numeric_limits<uint16_t >::max ();
215216
216- const uint8_t occupation_bit0
217- = x_plus1_valid && y_plus1_valid ? voxel_grid.getOccupation (VoxelGrid::LocalCoordinates (x_plus1, y_plus1, square_start.position .z )).value_or (0 ) : 0 ;
217+ const uint8_t occupation_bit0 = x_plus1_valid && y_plus1_valid
218+ ? voxel_grid.getOccupation (VoxelGrid::LocalCoordinates (x_plus1, y_plus1, square_start.position .z )).value_or (mesh_extruder_nr)
219+ : mesh_extruder_nr;
218220 const uint8_t occupation_bit1
219- = y_plus1_valid ? voxel_grid.getOccupation (VoxelGrid::LocalCoordinates (square_start.position .x , y_plus1, square_start.position .z )).value_or (0 ) : 0 ;
221+ = y_plus1_valid ? voxel_grid.getOccupation (VoxelGrid::LocalCoordinates (square_start.position .x , y_plus1, square_start.position .z )).value_or (mesh_extruder_nr)
222+ : mesh_extruder_nr;
220223 const uint8_t occupation_bit2
221- = x_plus1_valid ? voxel_grid.getOccupation (VoxelGrid::LocalCoordinates (x_plus1, square_start.position .y , square_start.position .z )).value_or (0 ) : 0 ;
222- const uint8_t occupation_bit3 = voxel_grid.getOccupation (square_start).value_or (0 );
224+ = x_plus1_valid ? voxel_grid.getOccupation (VoxelGrid::LocalCoordinates (x_plus1, square_start.position .y , square_start.position .z )).value_or (mesh_extruder_nr)
225+ : mesh_extruder_nr;
226+ const uint8_t occupation_bit3 = voxel_grid.getOccupation (square_start).value_or (mesh_extruder_nr);
223227
224228 const std::unordered_set<uint8_t > extruders = { occupation_bit0, occupation_bit1, occupation_bit2, occupation_bit3 };
225229 for (const uint8_t extruder : extruders)
226230 {
227- if (extruder == 0 )
231+ if (extruder == mesh_extruder_nr )
228232 {
229233 continue ;
230234 }
@@ -391,10 +395,14 @@ bool isInside(const VoxelGrid& voxel_grid, const VoxelGrid::LocalCoordinates& po
391395 * @param voxel_grid The current voxel grid to be checked. Some voxels may also be directly filled.
392396 * @param previously_evaluated_voxels The list of voxels that were just evaluated
393397 * @param sliced_mesh The pre-sliced mesh, used to check for points insideness
398+ * @param mesh_extruder_nr The main mesh extruder number
394399 * @return The list of new voxels to be evaluated
395400 */
396- boost::concurrent_flat_set<VoxelGrid::LocalCoordinates>
397- findVoxelsToEvaluate (VoxelGrid& voxel_grid, const boost::concurrent_flat_set<VoxelGrid::LocalCoordinates>& previously_evaluated_voxels, const std::vector<Shape>& sliced_mesh)
401+ boost::concurrent_flat_set<VoxelGrid::LocalCoordinates> findVoxelsToEvaluate (
402+ VoxelGrid& voxel_grid,
403+ const boost::concurrent_flat_set<VoxelGrid::LocalCoordinates>& previously_evaluated_voxels,
404+ const std::vector<Shape>& sliced_mesh,
405+ const uint8_t mesh_extruder_nr)
398406{
399407 boost::concurrent_flat_set<VoxelGrid::LocalCoordinates> voxels_to_evaluate;
400408
@@ -421,7 +429,7 @@ boost::concurrent_flat_set<VoxelGrid::LocalCoordinates>
421429
422430 if (! isInside (voxel_grid, voxel_around, sliced_mesh))
423431 {
424- voxel_grid.setOccupation (voxel_around, 0 );
432+ voxel_grid.setOccupation (voxel_around, mesh_extruder_nr );
425433 }
426434 else
427435 {
@@ -439,18 +447,20 @@ boost::concurrent_flat_set<VoxelGrid::LocalCoordinates>
439447 * @param voxels_to_evaluate The voxels to be evaluated
440448 * @param texture_data The lookup containing the rasterized texture data
441449 * @param deepness_squared The maximum deepness, squared
450+ * @param mesh_extruder_nr The main mesh extruder number
442451 */
443452void evaluateVoxels (
444453 VoxelGrid& voxel_grid,
445454 const boost::concurrent_flat_set<VoxelGrid::LocalCoordinates>& voxels_to_evaluate,
446455 const SpatialLookup& texture_data,
447- const coord_t deepness_squared)
456+ const coord_t deepness_squared,
457+ const uint8_t mesh_extruder_nr)
448458{
449459 voxels_to_evaluate.visit_all (
450460#ifdef __cpp_lib_execution
451461 std::execution::par,
452462#endif
453- [&voxel_grid, &texture_data, &deepness_squared](const VoxelGrid::LocalCoordinates& voxel_to_evaluate)
463+ [&voxel_grid, &texture_data, &deepness_squared, &mesh_extruder_nr ](const VoxelGrid::LocalCoordinates& voxel_to_evaluate)
454464 {
455465 const Point3D position = voxel_grid.toGlobalCoordinates (voxel_to_evaluate);
456466
@@ -460,12 +470,12 @@ void evaluateVoxels(
460470 if (nearest_occupation.has_value ())
461471 {
462472 const Point3D diff = position - nearest_occupation.value ().position ;
463- const uint8_t new_occupation = diff.vSize2 () <= deepness_squared ? nearest_occupation.value ().occupation : 0 ;
473+ const uint8_t new_occupation = diff.vSize2 () <= deepness_squared ? nearest_occupation.value ().occupation : mesh_extruder_nr ;
464474 voxel_grid.setOccupation (voxel_to_evaluate, new_occupation);
465475 }
466476 else
467477 {
468- voxel_grid.setOccupation (voxel_to_evaluate, 0 );
478+ voxel_grid.setOccupation (voxel_to_evaluate, mesh_extruder_nr );
469479 }
470480 });
471481}
@@ -502,14 +512,16 @@ void findBoundaryVoxels(boost::concurrent_flat_set<VoxelGrid::LocalCoordinates>&
502512 * @param sliced_mesh The pre-sliced mesh matching the voxel grid
503513 * @param texture_data The lookup containing the rasterized texture data
504514 * @param deepness_squared The maximum propagation deepness, squared
515+ * @param mesh_extruder_nr The main mesh extruder number
505516 */
506517void propagateVoxels (
507518 VoxelGrid& voxel_grid,
508519 boost::concurrent_flat_set<VoxelGrid::LocalCoordinates>& evaluated_voxels,
509520 const coord_t estimated_iterations,
510521 const std::vector<Shape>& sliced_mesh,
511522 const SpatialLookup& texture_data,
512- const coord_t deepness_squared)
523+ const coord_t deepness_squared,
524+ const uint8_t mesh_extruder_nr)
513525{
514526 uint32_t iteration = 0 ;
515527
@@ -519,11 +531,11 @@ void propagateVoxels(
519531
520532 // Make the list of new voxels to be evaluated, based on which were evaluated before
521533 spdlog::debug (" Finding voxels around {} voxels for iteration {}" , evaluated_voxels.size (), iteration);
522- evaluated_voxels = findVoxelsToEvaluate (voxel_grid, evaluated_voxels, sliced_mesh);
534+ evaluated_voxels = findVoxelsToEvaluate (voxel_grid, evaluated_voxels, sliced_mesh, mesh_extruder_nr );
523535
524536 // Now actually evaluate the candidate voxels, i.e. find their closest outside point and set the according occupation
525537 spdlog::debug (" Evaluating {} voxels" , evaluated_voxels.size ());
526- evaluateVoxels (voxel_grid, evaluated_voxels, texture_data, deepness_squared);
538+ evaluateVoxels (voxel_grid, evaluated_voxels, texture_data, deepness_squared, mesh_extruder_nr );
527539
528540 // Now we have evaluated the candidates, check which of them are to be processed next. We skip all the voxels that have only voxels with similar occupations around
529541 // them, because they are obviously not part of the boundaries we are looking for. This avoids filling the inside of the points clouds and speeds up calculation a lot.
@@ -542,8 +554,8 @@ void propagateVoxels(
542554 */
543555std::vector<Mesh> makeModifierMeshes (const Mesh& mesh, const std::shared_ptr<TextureDataProvider>& texture_data_provider)
544556{
545- const Settings& settings = mesh. settings_ ;
546- const size_t main_extruder = settings. get <size_t >(" extruder_nr" );
557+ const Settings& settings = Application::getInstance (). current_slice_ -> scene . settings ;
558+ const uint8_t mesh_extruder_nr = static_cast < uint8_t >(mesh. settings_ . get <size_t >(" extruder_nr" ) );
547559
548560 // Fill a first voxel grid by rasterizing the triangles of the mesh in 3D, and assign the extruders according to the texture. This way we can later evaluate which extruder
549561 // to assign any point in 3D space just by finding the closest outside point and see what extruder it is assigned to.
@@ -558,9 +570,9 @@ std::vector<Mesh> makeModifierMeshes(const Mesh& mesh, const std::shared_ptr<Tex
558570
559571 // Create the voxel grid and initially fill it with the rasterized mesh triangles, which will be used as spatial reference for the texture data
560572 VoxelGrid voxel_grid (bounding_box, resolution);
561- if (! makeVoxelGridFromTexture (mesh, texture_data_provider, voxel_grid, main_extruder ))
573+ if (! makeVoxelGridFromTexture (mesh, texture_data_provider, voxel_grid, mesh_extruder_nr ))
562574 {
563- // Texture is filled with 0s , don't bother doing anything
575+ // Texture is filled with the main extruder , don't bother doing anything
564576 return {};
565577 }
566578
@@ -576,9 +588,9 @@ std::vector<Mesh> makeModifierMeshes(const Mesh& mesh, const std::shared_ptr<Tex
576588 spdlog::debug (" Get initially filled voxels" );
577589 boost::concurrent_flat_set<VoxelGrid::LocalCoordinates> previously_evaluated_voxels;
578590 voxel_grid.visitOccupiedVoxels (
579- [&previously_evaluated_voxels](const auto & voxel)
591+ [&previously_evaluated_voxels, &mesh_extruder_nr ](const auto & voxel)
580592 {
581- if (voxel.second > 0 )
593+ if (voxel.second != mesh_extruder_nr )
582594 {
583595 previously_evaluated_voxels.insert (voxel.first );
584596 };
@@ -590,9 +602,9 @@ std::vector<Mesh> makeModifierMeshes(const Mesh& mesh, const std::shared_ptr<Tex
590602 const coord_t estimated_iterations = estimated_min_deepness / resolution;
591603 spdlog::debug (" Estimated {} iterations" , estimated_iterations);
592604
593- propagateVoxels (voxel_grid, previously_evaluated_voxels, estimated_iterations, sliced_mesh, texture_data, deepness_squared);
605+ propagateVoxels (voxel_grid, previously_evaluated_voxels, estimated_iterations, sliced_mesh, texture_data, deepness_squared, mesh_extruder_nr );
594606
595- return makeMeshesFromVoxelsGrid (voxel_grid);
607+ return makeMeshesFromVoxelsGrid (voxel_grid, mesh_extruder_nr );
596608}
597609
598610void makeMaterialModifierMeshes (const Mesh& mesh, MeshGroup* meshgroup)
0 commit comments