Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

difference operation returns random results #1096

Closed
dlednik opened this issue Dec 20, 2020 · 7 comments
Closed

difference operation returns random results #1096

dlednik opened this issue Dec 20, 2020 · 7 comments

Comments

@dlednik
Copy link

dlednik commented Dec 20, 2020

So I have 2 objects. Object A and B which represents holes I want to cut out of A.

When I run difference like below it gives me random results. Sometimes the result is A-B like expected, but sometimes it returns B-A as the result. Is this expected behaviour?
Engine in this case is blender

self.stl.difference(holes_elements[0], engine=self.ENGINE)

So this is what I expect always to get back:
image

But like I said sometimes it returns this:
image

It cuts A from B and returns B-A as result:
image

@dlednik
Copy link
Author

dlednik commented Dec 20, 2020

I made a workaround in my code for now:
https://github.com/Mambix/co2tools/blob/master/co2tools/stl/builder.py#L171

It just makes a couple of itterations and saves the result with highest mass.
No ideal, but for the size of objects I'm using is working for now.

@MarwinSc
Copy link

I'm having the same problem, I tried different blender versions, but the results of the difference operation is always random.

@dlednik
Copy link
Author

dlednik commented Jan 1, 2021

I also noticed that sometimes even with the correct A-B result returned there are some holes missing in my parts. scad cuts them correctly, but blender misses certain cuts.

@markstor
Copy link

markstor commented Feb 5, 2021

I'm having the same issue, I think that problem is that the objects order in Blender is random. My guess is that the objects are alphabetically ordered, and their names are the random temporary stl files generated by trimesh.

I haven't found an elegant way to reference imported stls in Blender, without having to select "blindly" the object.
I attach a modified blender template that solved the issue for me: modified_blender_boolean.txt

I've tested it minimally with Blender 2.91 and Blender 2.79 with the code below

import sys
import time
from pathlib import Path

import trimesh
from trimesh.interfaces.blender import _blender_executable
from trimesh.util import log

blenders_dir = Path(_blender_executable).parent.parent

def test(iterations=10):
    for blender_exe in blenders_dir.rglob("blender.exe"):
        blender_version = next(blender_exe.parent.glob("*2.*")).name
        log.warning("Testing Blender {}".format(blender_version))
        _blender_executable = str(blender_exe)
        good_bools = 0
        start = time.time()
        for _ in range(iterations):  # Montecarlito
            flat_box = trimesh.primitives.creation.box((50, 50, 10))
            tall_box = trimesh.primitives.creation.box((15, 15, 20))

            donut = flat_box.difference(tall_box, engine="blender")
            # donut should be a doughnut, but it can be two boxes
            if donut.extents[0] < 49:
                log.info("Bad boolean")
            else:
                log.info("Good boolean")
                good_bools += 1
        log.warning("Blender {} succes rate {:0.2f}%. {:0.2f} seconds".format(blender_version, good_bools * 100.0 / iterations, time.time() - start))


def change_bool_script(script_path):
    from trimesh.resources import _cache
    log.warning("Changing script to {}".format(script_path))
    with open(script_path, "r") as f:
        _cache[('blender_boolean.py.template', True, False)] = f.read()


if __name__ == "__main__":
    import logging
    logging.basicConfig(level=logging.WARNING, stream=sys.stdout, format="%(message)s")

    test()
    change_bool_script(r"modified_blender_boolean.txt")
    test()

@mikedh
Copy link
Owner

mikedh commented Apr 4, 2021

I believe this was fixed by #1177 so closing for now.

@mikedh mikedh closed this as completed Apr 4, 2021
@dlednik
Copy link
Author

dlednik commented Apr 5, 2021

@mikedh what version will this fix be included in?
I want to test it out with my code :)

@mikedh
Copy link
Owner

mikedh commented Apr 5, 2021

It's in the latest release, if you do a pip install --upgrade trimesh it should get it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants