raysect / source

The main source repository for the Raysect project.
http://www.raysect.org
BSD 3-Clause "New" or "Revised" License
88 stars 23 forks source link

Cone or subtract segfaulting #251

Closed Mateasek closed 5 years ago

Mateasek commented 5 years ago

Following code appears to segfault:

`cylinder1 = Cone(radius=0.565,height = 0.01, transform =translate(0, 0, -0.005)) cylinder2 = Cone(radius=0.555,height = 0.02, transform =translate(0, 0, -0.01))

radiator = Subtract(cylinder1, cylinder2, parent = world, material=UnityVolumeEmitter())`

Mateasek commented 5 years ago

update

'a = 0.25/(np.sqrt(2np.pi0.56)) cylinder1 = Cylinder(radius= 0.56 + a/2, height = a, transform =translate(0, 0, -a/2))

cylinder2 = Cylinder(radius= 0.56 - a/2, height = 1, transform =translate(0, 0, -0.5))

box1 = Box(lower=Point3D(-1.5,0,-1), upper=Point3D(1.5, 0, 1)) box2 = Box(lower=Point3D(0,-1,-1), upper=Point3D(0, 1, 1))

box = Box(lower=Point3D(0, 0, 0), upper=Point3D(1,1,1))

radiation = UniformVolumeEmitter(emission_spectrum=ConstantSF(1.0), scale=1.5e5) radiator1 = Subtract(cylinder1, cylinder2) radiator2 = Subtract(radiator1, box1) radiatior3 = Subtract(radiator2, box2, parent = world, material=UnityVolumeEmitter()) '

also causes segmentation fault. Maybe it is not only Cone or it is me.

CnlPepper commented 5 years ago

I suspect a bug may have crept in to Subtract during the last set of changes. Which version of raysect is installed?

CnlPepper commented 5 years ago

I've tested this and have been unable to replicate the issue. Could you try rebuilding the code using:

dev/build.sh --force

in the raysect root folder?

Mateasek commented 5 years ago

I suspect a bug may have crept in to Subtract during the last set of changes. Which version of raysect is installed?

0.5.4

I've tested this and have been unable to replicate the issue. Could you try rebuilding the code using:

dev/build.sh --force

in the raysect root folder?

I did ./dev/build.sh --force and ./dev/clean.sh & ./dev/build.sh --force and it did not help. I will upload the python file into cherab compass repository to provide the whole code causing this problem.

CnlPepper commented 5 years ago

hmm, I can't replicate it so far. Could you try running the csg.py demo? If that fails then it is probably a local installation issue. It might be worth updating cython to the latest version and try dev/clean.sh and dev/build.sh.

Mateasek commented 5 years ago

hmm, I can't replicate it so far. Could you try running the csg.py demo? If that fails then it is probably a local installation issue. It might be worth updating cython to the latest version and try dev/clean.sh and dev/build.sh.

I will try to do this on the computer I spotted the problem on.

Meanwhile I installed cherab & raysect on my office computer and tested the example I had problems with. I added the file to branch segfault on cherab/compass (compass/demos/incident_radiation.py ). While creating the file I realised I (again :-( ) merged two problems into one. Anyway the run is ending in segfault if https://github.com/cherab/compass/blob/e3aae705746eb3101d1bcf8ed0c6fdda5b917505/demos/incident_radiation.py#L76-L77 are used. This might be because I have defined the boxes to be actually planes. Could that be the problem? When I define the boxes correctly https://github.com/cherab/compass/blob/e3aae705746eb3101d1bcf8ed0c6fdda5b917505/demos/incident_radiation.py#L74-L75 the script runs without any problems.

CnlPepper commented 5 years ago

Hi @Mateasek, I've recreated the problem. Will look into it asap.

CnlPepper commented 5 years ago

Ok it is crashing in the UnityVolumeEmitter(). I am curious why you are trying to slice a plane from the cylinder. I think there are some infinities/recursion creeping in.

Mateasek commented 5 years ago

Well I was using volume emitter because I am newbie and I was playing around :-)

Anyway I'm happy you have Isolated the reason. Good luck with fixing it!

CnlPepper commented 5 years ago

Ok got it, found the issue. Unfortunately it is something we cannot fix easily... I'll need to think about it (though tbh it is an extreme corner case that was only found by making a mistake in the scene setup - using infinite planes).

A pure volume material has no surface, but in the raytracer implementation there is a primitive surface bounding the volume and we therefore need to skip it. The pure volume therefore materials re-fire the ray from the other side of the primitive surface and reduces the ray depth count by 1 so it appears that the surface is not there. Unfortunately if there are two coincident geometric surfaces (as is the case if you subtract an infinite plane from a volume), there is a chance of either surface being intersected with first. One of those surface will be labelled as an "exterior surface". If this surface is intersected first (purely chance), the ray is moved in the wrong direction and will keep re-intersecting the surface again and again until the stack is exceeded.

I'll see if I can find a mitigation just for robustness, but for now, don't subtract infinite planes from a volume - it basically does nothing anyway! ;) :)

CnlPepper commented 5 years ago

So your code should not have the last two subtractions. It should just be:

radiation = UniformVolumeEmitter(emission_spectrum=ConstantSF(1.0), scale=1.5e5)
radiator = Subtract(cylinder1, cylinder2, parent=world, material=radiation)

The other lines literally do nothing but break the code.