News:

Latest addition to the collection: Prefab Maker

Main Menu

Boolean Ops runtime code

Started by MediaGiant, September 16, 2014, 01:24:16 AM

Previous topic - Next topic

MediaGiant

The Boolean operations were written to be performed while in editor mode but the classes are public so you can adapt the following script to perform the operations during runtime:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using CSG;

public class Test : MonoBehaviour
{
public enum Operation { Subtract, Union, Intersection };
List<Polygon> origPolygons;
GameObject gameObjectA;
GameObject gameObjectB;
Transform[] childs = new Transform[2];
public Operation operation = Operation.Subtract;

// Use this for initialization
void Start ()
{
gameObjectA = GameObject.Find("Target");
gameObjectB = GameObject.Find("Brush");
childs[0] = gameObjectA.transform;
childs[1] = gameObjectB.transform;
origPolygons = new List<Polygon>();
CSG.CSG.triIndex = 0; // always set this to zero before all operations
CSG.CSG.transform = gameObjectA.transform;
CSG.CSG A = CSG.CSG.fromMesh(childs[0].GetComponent<MeshFilter>().sharedMesh, childs[0], true);
CSG.CSG B = CSG.CSG.fromMesh(childs[1].GetComponent<MeshFilter>().sharedMesh, childs[1], false);
origPolygons.AddRange(A.polygons);
origPolygons.AddRange(B.polygons);
CSG.CSG result = null;

if (operation == Operation.Subtract)
{
result = A.subtract(B);
}

if (operation == Operation.Union)
{
result = A.union(B);
}

if (operation == Operation.Intersection)
{
result = A.intersect(B);
}

if (result != null)
{
result.toMesh(gameObjectA, gameObjectB);
}
}

// Update is called once per frame
void Update ()
{

}
}


To use the code start by copying the following three DLLs to your project folder:
MeshMaker.dll
ComputationalGeometry.dll
VectorGeometry.dll

(or just the BooleanOps.dll if you don't have MeshMaker)

Then attach the script above to a new empty game object.
Create two new cubes and rename them to "Target" and "Brush".
Position the cubes so that they are intersecting and click the play button.

Make Allry

#1
Hi, im new in MeshMaker, but that topic is exacly what i need to do, use  the boolean ops in runtime.

How I'm supose to import the library and use?

All package is in .dll format, and I never use dlls in unity before.

MediaGiant

Hi, welcome to the forum and thank you for your purchase of MeshMaker. I have updated the code above to show an example of how to perform the operations in runtime. I hope this helps but if have any probs please let me know.

remigius

Hi, first I must say Mesh Maker (Boolean Ops in particular) seems like a super useful tool. I am trying to use Boolean Ops in runtime, so I made a function for quick access to the subtract functionality. I am creating the targetGhost copy because I want to do some calculations on it and then throw it away. The original GameObject must stay intact.

This is the function:
GameObject BooleanSubtract(GameObject target, GameObject remove) {
// Clone target for boolean operation
GameObject targetGhost = (GameObject) GameObject.Instantiate(target);

// Subtract candidate from target
CSG.CSG.triIndex = 0; // always set to 0 before all operations
CSG.CSG.transform = target.transform;
CSG.CSG A = CSG.CSG.fromMesh(target.GetComponent<MeshFilter>().sharedMesh, target.transform, true);
CSG.CSG B = CSG.CSG.fromMesh(remove.GetComponent<MeshFilter>().sharedMesh, remove.transform, false);
CSG.CSG result = A.subtract(B);
result.toMesh(targetGhost, targetGhost);

return targetGhost;
}


but occasionally (not always) I get a StackOverflow error:

StackOverflowException: The requested operation caused a stack overflow.
CSG.Node.build (System.Collections.Generic.List`1 polys)
CSG.Node.build (System.Collections.Generic.List`1 polys)
...etc



Any idea what could be the problem?

MediaGiant

Hi remigius, a stack overflow usually indicates a memory problem. I've never seen this myself with this program but I would look at using DestroyImmeshmakete on the targetGhost mesh between operations.

remigius

#5
Hi meshmakeGiant, thanks for your reply. Unfortunately, DestroyImmeshmakete has no effect with regards to the StackOverflow. As a fallback, is there any way to catch this Exception and handle it?

MediaGiant

The core code is not optimized to reduce the number of triangles produced. What is most likely happening is that with each successive operation the number of triangles is growing so large that internal loops within the code are unable to deal with the number of iterations required to perform the operation.

The program as it stands is okay for one or two operations on the same mesh but will need to be optimized to reduce the triangle count after each operation which will require a new mesh data structure that contains adjacency information. A big job but if you are interested in creating your own version you can grab the original source here at https://github.com/omgwtfgames/csg.cs