pyslm icon indicating copy to clipboard operation
pyslm copied to clipboard

Unexpected Slicing and Hatching result

Open MarcelHeu opened this issue 1 year ago • 1 comments

Hey,

For some models i got an unexpected result after using the slicing and hatching algorithm. I used a slightly modified version of your "example_3d_multithread.py" script as a template to visualise the unexpected results for you:

expected Result: GoodResult

unexpected Result: BadResult

As you can see some areas are closed incorrectly in some layers within the model. I dont know exactly how to fix this problem and if this is an issue with the model itself (model should be watertight), the slicing algorithm or the hatching algorithm. Maybe you have some ideas. You can find the used source code and the *.stl file below.

ScriptAndModel.zip

"""
A simple example showing how to use PySLM for generating slices across a 3D model.
THhs example takes advantage of the multi-processing module to run across multiple threads.
"""
import pyslm
import pyslm.visualise
from pyslm import hatching as hatching
import numpy as np
import time

from multiprocessing import Manager
from multiprocessing.pool import Pool
from multiprocessing import set_start_method

def calculateLayer(input):
    # Typically the hatch angle is globally rotated per layer by usually 66.7 degrees per layer
    d = input[0]
    zid= input[1]

    layerThickness = d['layerThickness']
    solidPart = d['part']

    # Create a StripeHatcher object for performing any hatching operations
    myHatcher = hatching.Hatcher()

    # Set the base hatching parameters which are generated within Hatcher
    myHatcher.hatchAngle            = 45 + zid * 66.7
    myHatcher.volumeOffsetHatch     = 0.07
    myHatcher.spotCompensation      = 0.1
    myHatcher.numInnerContours      = 0
    myHatcher.numOuterContours      = 1
    myHatcher.hatchDistance         = 0.12
    myHatcher.hatchSortMethod       = hatching.AlternateSort()

    # Slice the boundary
    geomSlice = solidPart.getVectorSlice(zid*layerThickness)

    # Hatch the boundary using myHatcher
    layer = myHatcher.hatch(geomSlice)

    if layer:
        # The layer height is set in integer increment of microns to ensure no rounding error during manufacturing
        layer.z = int(zid*layerThickness * 1000)
        layer.layerId = int(zid)

        return layer
    else:
        return None

def main():
    set_start_method("spawn")

    # Imports the part and sets the geometry to  an STL file (frameGuide.stl)
    solidPart = pyslm.Part('bridge')
    solidPart.setGeometry('bridge_slm_cad.stl')

    solidPart.origin[0]     = 0.0
    solidPart.origin[1]     = 0.0
    solidPart.scaleFactor   = 1.0
    solidPart.rotation      = [0.0, 0.0, 0.0]
    solidPart.dropToPlatform()
    print(solidPart.boundingBox)

    # Set the layer thickness
    layerThickness = 0.03 # [mm]

    #Perform the hatching operations
    print('Hatching Started')

    layers = []

    p = Pool(processes=4)

    d = Manager().dict()
    d['part'] = solidPart
    d['layerThickness'] = layerThickness

    # Rather than give the z position, we give a z index to calculate the z from.
    numLayers = solidPart.boundingBox[5] / layerThickness
    z = np.arange(0, numLayers).tolist()

    # The layer id and manager shared dict are zipped into a list of tuple pairs
    processList = list(zip([d] * len(z), z))

    startTime = time.time()

    # uncomment to test the time processing in single process
    #for pc in processList:
    #   calculateLayer(pc)

    layers = p.map(calculateLayer, processList)

    print('Multiprocessing time {:.1f} s'.format(time.time()-startTime))
    p.close()

    print('Completed Hatching')
    
    return layers


if __name__ == '__main__':
    layers = main()
    
    for k in range(164, 171, 1):
        pyslm.visualise.plotSequential(layers[k])

For some other models i also have something like this for example:

  • defective small contours and a incorrectly closed area BadResult_02

MarcelHeu avatar Jul 19 '22 11:07 MarcelHeu