Java implementation of BSP based CSG (Constructive Solid Geometry)

Overview

JCSG

Build Status Download Javadocs

Java implementation of BSP based CSG (Constructive Solid Geometry). It is the only simple and free Java implementation I am aware of. This implementation uses an optimized CSG algorithm based on csg.js (see CSG and Node classes). Thanks to the author for creating the csg.js library.

There's also the related VCSG library, a plugin for VRL-Studio and two extension libraries: JCSG-MeshExtension and JCSG-PathExtension.

In addition to CSG this library provides the following features:

  • optimized difference() and union() operations (many thanks to Sebastian Reiter)
  • extrusion of concave, non-intersecting polygons (uses Poly2Tri for triangulation)
  • convex hull (uses QuickHull3D)
  • weighted transformations (Scale, Rotation, Translation and Mirror)
  • STL import and export (STLLoader from Fiji)
  • OBJ export including material information (see screenshot below)
  • supports conversion of CSG's to JavaFX 3D nodes
  • 3d text support (using FXyz)

JCSG on stackoverflow.

To see what's possible with JCSG try JFXScad.

How to Build JCSG

Requirements

  • Java >= 11
  • Internet connection (dependencies are downloaded automatically)
  • IDE: Gradle Plugin (not necessary for command line usage)

IDE

Open the JCSG Gradle project in your favourite IDE (tested with NetBeans 7.4) and build it by calling the assemble task.

Command Line

Navigate to the Gradle project (e.g., path/to/JCSG) and enter the following command

Bash (Linux/OS X/Cygwin/other Unix-like shell)

bash gradlew assemble

Windows (CMD)

gradlew assemble

Code Sample:

// we use cube and sphere as base geometries
CSG cube = new Cube(2).toCSG();
CSG sphere = new Sphere(1.25).toCSG();

// perform union, difference and intersection
CSG cubePlusSphere = cube.union(sphere);
CSG cubeMinusSphere = cube.difference(sphere);
CSG cubeIntersectSphere = cube.intersect(sphere);
        
// translate geometries to prevent overlapping 
CSG union = cube.
        union(sphere.transformed(Transform.unity().translateX(3))).
        union(cubePlusSphere.transformed(Transform.unity().translateX(6))).
        union(cubeMinusSphere.transformed(Transform.unity().translateX(9))).
        union(cubeIntersectSphere.transformed(Transform.unity().translateX(12)));
        
// save union as stl
try {
    FileUtil.write(
            Paths.get("sample.stl"),
            union.toStlString()
    );
} catch (IOException ex) {
    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}

Thanks to

Comments
  • Feature Add to resolve #16

    Feature Add to resolve #16

    In this feature a function should be added that takes in a CSG and a slice plane and returns a list of polygons of all the features at that plane. This would add the feature to resolve #16

    opened by madhephaestus 34
  • Extrude feature has issues when complex paths from text fonts are used

    Extrude feature has issues when complex paths from text fonts are used

    I have been attempting to make an automatic extrusion from text using Javas font's and the PathIterator interface. This is the gist that is working in BowlerStudio demonstrating that the points are being created in a sane way and in the right locations:

    https://gist.github.com/madhephaestus/da78cb13a62c1a5c691f

    If you uncomment line 45, you will get the error.

    I use a simple loop to create the array list of points from the PathIterator then extrude the points with the Extrude.points. This causes this exception:

    java.lang.RuntimeException: Intersecting Constraints eu.mihosoft.vrl.v3d.ext.org.poly2tri.DelaunayTriangle@152491d5 is constrained Edge accross [389.1875,-64.78125] at eu.mihosoft.vrl.v3d.ext.org.poly2tri.DTSweep.flipEdgeEvent(DTSweep.java:614) at eu.mihosoft.vrl.v3d.ext.org.poly2tri.DTSweep.flipEdgeEvent(DTSweep.java:654) at eu.mihosoft.vrl.v3d.ext.org.poly2tri.DTSweep.edgeEvent(DTSweep.java:591) at eu.mihosoft.vrl.v3d.ext.org.poly2tri.DTSweep.edgeEvent(DTSweep.java:360) at eu.mihosoft.vrl.v3d.ext.org.poly2tri.DTSweep.sweep(DTSweep.java:136) at eu.mihosoft.vrl.v3d.ext.org.poly2tri.DTSweep.triangulate(DTSweep.java:103) at eu.mihosoft.vrl.v3d.ext.org.poly2tri.Poly2Tri.triangulate(Poly2Tri.java:127) at eu.mihosoft.vrl.v3d.ext.org.poly2tri.Poly2Tri.triangulate(Poly2Tri.java:117) at eu.mihosoft.vrl.v3d.ext.org.poly2tri.Poly2Tri.triangulate(Poly2Tri.java:86) at eu.mihosoft.vrl.v3d.ext.org.poly2tri.PolygonUtil.concaveToConvex(PolygonUtil.java:99) at eu.mihosoft.vrl.v3d.Extrude.extrude(Extrude.java:92) at eu.mihosoft.vrl.v3d.Extrude.points(Extrude.java:82) at eu.mihosoft.vrl.v3d.Extrude$points.call(Unknown Source) at Script1.run(Script1.groovy:57) at com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine.runGroovy(ScriptingEngine.java:376) at com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine.inlineScriptRun(ScriptingEngine.java:340) at com.neuronrobotics.bowlerstudio.scripting.ScriptingEngineWidget$5.run(ScriptingEngineWidget.java:426)

    javacadtext

    opened by madhephaestus 11
  • Unit test to demonstrate #15

    Unit test to demonstrate #15

    I wrote a stripped down unit test to demonstrate the issue i have been describing in #15 . This unit test will test to see that when the extrude function is called on convex polygons, that the triangulation function does not fall off the edge and begin placing triangles inside out.

    opened by madhephaestus 7
  • Creating a Polygon

    Creating a Polygon

    Hi,

    I am unable to reproduce the following example (found here)

    List<Vector3d> vertices = new ArrayList<>();
    
    vertices.add(Vector3d.xyz(0, 0, 0));
    vertices.add(Vector3d.xyz(50, 25, 0));
    vertices.add(Vector3d.xyz(100, 0, 0));
    vertices.add(Vector3d.xyz(0, 100, 0));
    
    List<Polygon> t = Polygon.fromConcavePoints(vertices);
    CSG csg = CSG.fromPolygons(t);
    

    All I get is this error:

    This static method of interface Vector3d can only be accessed as Vector3d.xyz

    Again, I might be doing something wrong and would really appreciate some help.

    Respectfully

    opened by solub 5
  • How to import OBJ ?

    How to import OBJ ?

    Thank you for this wonderful library @miho .

    I'm testing the different functions of JCSG and would like to know how to import an OBJ file.

    Writing MyObj = Importer3D.load("column.obj") returns the following error:

    Unknown 3D file format [obj] at eu.mihosoft.jcsg.ext.openjfx.importers.Importer3D.loadIncludingAnimation(Importer3D.java:139)

    Another attempt with MyObj= ObjImporter("C:/Users/solub/Desktop/meshes/column.obj") returns:

    java.net.MalformedURLException: unknown protocol: c at java.net.URL.(URL.java:600) at java.net.URL.(URL.java:490) at java.net.URL.(URL.java:439) at eu.mihosoft.jcsg.ext.openjfx.importers.obj.ObjImporter.(ObjImporter.java:108) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

    Am I doing something wrong here ?

    opened by solub 5
  • Feature request: Processing library

    Feature request: Processing library

    Many people would be really happy if a CSG library existed for Processing. Just saying ;)

    Processing (processing.org) is based in Java 7. I took a look at porting the code myself, but first I would have to study how to port Java 8 code to Java 7. Would that be a complicated task? Never did Java 8.

    I think a possible Processing CSG library would include only a subset of the JCSG features, since it's already possible to create spheres, cubes, and other shapes, it's easy to display them simply by calling shape(myShape), where myShape is of type PShape. Processing has many 3D libraries available with mesh generation features (http://hg.postspectacular.com/toxiclibs/, http://hemesh.wblut.com/ and others), which offer iso surfaces, convex hull, polyhedrons, tubes, bending, stretching, and other kinds of distortion. Only CSG is missing :)

    Are there plans for such a Processing library? Otherwise, do you know of a Java 8 to 7 translation guide?

    Thanks!

    opened by hamoid 5
  • AWT dependencies removed from clean-room text extrude

    AWT dependencies removed from clean-room text extrude

    I added a unit test to verify that the text extrude functions execute without error. I also verified the STL produced represents the text entered, in the correct orientation.

    opened by madhephaestus 4
  • Text3D Depends on a specific version of JCSG

    Text3D Depends on a specific version of JCSG

    JCSG depends on extfxyz, which in turn dependes on JCSG 0.3.2, causing a dependency loop and importing out of date classes. This breaks downstream implementations.

    https://repo1.maven.org/maven2/eu/mihosoft/ext/org/fxyz/extfxyz/0.4/extfxyz-0.4.pom

    If they both depend on each other, maybe they should be merged?

    opened by madhephaestus 3
  • samples in the JCSG

    samples in the JCSG

    First of all, it's a very impressive work.

    The project is easy to setup. However, when I tried the Egg.java or EggCup.java in the sample package It gives me these:

    Exception in thread "main" java.lang.StackOverflowError at java.util.Arrays.copyOf(Unknown Source) at java.util.ArrayList.grow(Unknown Source) at java.util.ArrayList.ensureExplicitCapacity(Unknown Source) at java.util.ArrayList.ensureCapacityInternal(Unknown Source) at java.util.ArrayList.add(Unknown Source) at eu.mihosoft.vrl.v3d.Plane.splitPolygon(Plane.java:159) at eu.mihosoft.vrl.v3d.Node.lambda$2(Node.java:244) at eu.mihosoft.vrl.v3d.Node$$Lambda$9/4952965.accept(Unknown Source) at java.util.ArrayList.forEach(Unknown Source) at eu.mihosoft.vrl.v3d.Node.build(Node.java:243)

    I'm not sure it's a bug or something I run the samples not correctly.

    Please advise.

    Thanks.

    opened by cznlzq 3
  • Unioning spheres ends up with too many polygons

    Unioning spheres ends up with too many polygons

    After unioning about 70 spheres together, I end up with a lot of polygons, as shown this image:

    image

    It also takes 5+ minutes to do all of the unions. Do you have any ideas on how to speed this up/clean up the end result? Thanks!

    opened by danwinkler 3
  • How to set color to Java JCSG object? [JavaFX]

    How to set color to Java JCSG object? [JavaFX]

    I'm currently using the Java JCSG library to create Constructive Solid Geometry objects such as intersections, unions and difference between 3D objects. Using the JCSG library, I have the following code for creating objects (cube in this case)

    private static CSG createCube(double w, double h, double d) { return new Cube(w, h, d).toCSG(); } and whenever I want to set the colour of this specific CSG object I use the following

    private static CSG color(CSG shape, Color c) { return shape.color(c); } However when I transform these objects to a MeshView and pass them to the javafx.scene.Group the color is the default one (red): ` Group world = new Group(); System.out.println(this.objects.size()); for (CSG p : this.objects) { var x = p.toJavaFXMesh().getAsMeshViews().get(0);

            for(Material m: p.toJavaFXMesh().getMaterials()){
                System.out.println(m.toString());
    
                // System.out.println(m1.getDiffuseColor().toString());
                x.setMaterial((PhongMaterial)m);
            }
            world.getChildren().add(x);
        }
    
        Scene scene = new Scene(world, WIDTH, HEIGHT, true);
        scene.setFill(Color.PALETURQUOISE);
        scene.setCamera(camera);
    
        // initMouseControl(world, scene, primaryStage);
        addEventHandlers(scene, camera);
        primaryStage.setTitle("Pane");
        primaryStage.setScene(scene);
        primaryStage.show();
    

    Where this.objects holds all the objects that I created in another class. package me.emil;

    import javafx.scene.paint.Color; import me.emil.helpers.Pane;

    public class App { public static void main(String[] args) { CSGStorage singleton = CSGStorage.getInstance(); var x = singleton.sphere(50); x = singleton.translate(x, 100, 0, 0); x = singleton.color(x, Color.YELLOW); singleton.addPrimitive(x);

        Pane p = new Pane();
        p.launchPane();
    }
    

    } `

    opened by elozev 2
  • Why does

    Why does "difference" keep parts in the CSG that don't "intersect"

    Hi,

    We're working with your library and noticed something curious, why does the "substract" function keep parts that don't intersect with the given part?

    Imho if they don't intersect then A.difference(B) should just return A

    (we ran into a visual issue and now fixed it by first checking if the parts intersect before executing the difference)

    image

    opened by ZenoGillis 1
  • Fix the stackOverflow issue in #54

    Fix the stackOverflow issue in #54

    This is a fix to the stack overflow issue in the plane split function. If a plane that comes in that is not as flat as the fixed Plane.EPSILON value, then the algorithm would recourse until a crash.

    This change measures the epsilon off of the incoming polygon to set the epsilon values accurately for each incoming polygon.

    opened by madhephaestus 0
  • Difficulty locating .jar file download

    Difficulty locating .jar file download

    [Disclaimer, I may have only had trouble because I'm dumb]

    The .jar download link was a bit hard for me to find. There's the very small link to bintray from the README, then it says "No direct downloads selected for this package," so you have to click "Files," then it looks like there's nothing there until you see the quite tiny "0.5.7" folder, then the right download is in the list with a bunch of other stuff... maybe I'm just dumb but I wasted a good amount of time thinking there was no .jar download and trying to figure out how to use Gradle with the source code to try and make something importable to my project.

    Edit: I've now been using the library for a bit and it's freaking fantastic. Just thought I'd mention my appreciation!

    TL;DR Please someone smarter than me make the link easier to find.

    opened by merlinlikethewizard 0
  • Cylinder rotation in Z axis

    Cylinder rotation in Z axis

    Can anyone tell me whether cylinder rotation in Z axis is working or not?

    It seems to fail for me - not sure if I'm doing something wrong.

    In this example I am trying to build a square pyramid out of cylindrical poles and can't get it to work at all. Any thoughts?

    This is my test code.

    import eu.mihosoft.jcsg.CSG;
    import eu.mihosoft.jcsg.Cylinder;
    import eu.mihosoft.jcsg.FileUtil;
    import eu.mihosoft.vvecmath.Transform;
    
    import java.io.IOException;
    import java.nio.file.Paths;
    
    public class PoleTest
    {
        public static void main(String[] args) throws IOException
        {
            CSG result = new PoleTest().toCSG();
            FileUtil.write(Paths.get("PoleTest.stl"), result.toStlString());
        }
    
        public CSG pole(double length, double radius, double rotX, double rotY, double rotZ, double trX, double trY, double trZ)
        {
            System.out.printf("rotX=%.2f rotY = %.2f rotZ = %.2f%n", rotX, rotY, rotZ);
            CSG innerCyl = new Cylinder(radius, length, 16).toCSG();
            return innerCyl.transformed(Transform.unity().rotX(rotX).rotY(rotY).rotZ(rotZ))
                .transformed(Transform.unity().translate(trX, trY, trZ));
        }
    
        public CSG toCSG()
        {
            double armLength = 150;
            double armRadius = 5;
    
            CSG pole1 = pole(armLength, armRadius,0, 60,0, 0,0,45);
            CSG pole2 = pole(armLength*2, armRadius,30, 45,45, armLength, 0, 0);
            CSG pole3 = pole(armLength, armRadius,45, 0,90, 0, armLength,0);
            CSG pole4 = pole(armLength, armRadius,45, 90,0, armLength,armLength,0);
            return pole1.union(pole2).union(pole3).union(pole4);
        }
    }
    
    
    opened by skanga 0
  • Multiple uinions cause StackOverflow Error

    Multiple uinions cause StackOverflow Error

    I've written this code:

    public class Main {
    
        public static void main(String[] args) throws IOException {
            CSG cube = STL.file(Paths.get("cube.stl"));
    
            CSG union = cube;
            for (int x = 0; x < 100; x++) {
                union = union.union(cube.transformed(Transform.unity().translateX(x * 10)));
            }
    
            try {
                FileUtil.write(Paths.get("sample.stl"), union.toStlString());
            } catch (IOException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    
    }
    

    But after 26 unions i get this error:

    Exception in thread "main" java.lang.StackOverflowError
    at java.util.stream.AbstractPipeline.wrapSink(Unknown Source)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
    at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
    at java.util.stream.ReferencePipeline.collect(Unknown Source)
    at eu.mihosoft.jcsg.Node.build(Node.java:244)
    at eu.mihosoft.jcsg.Node.build(Node.java:265)
    
    

    I'm trying to combine multiple objects to one but unluckily i get this error :/

    opened by Fliens 2
  • Split in two objects after difference

    Split in two objects after difference

    Hello and thanks for your work, I am struggling with a little problem. Is it possible to split an object in two by building the difference with another object.

    Screenshot from 2019-12-03 11-10-01 Screenshot from 2019-12-03 11-10-39

    How can I split the green object in two CSGs? I want to keep the lower part.

    Thanks.

    opened by iibPScheich 1
Owner
Michael Hoffer
Computer Scientist, Developer, Artist
Michael Hoffer
A GUI-based file manager based on a Java file management and I/O framework using object-oriented programming ideas.

FileManager A GUI-based file manager based on a Java file management and I/O framework using object-oriented programming ideas. Enables folder creatio

Zongyu Wu 4 Feb 7, 2022
A maven-based JavaFX Asteroids game based on a tutorial from Lee Stemkoski

JavaFX Asteroids About This is a maven-based project which implements a JavaFX Asteroids Game. The code is based on a tutorial from Lee Stemkoski whic

null 2 Mar 2, 2022
Tray Icon implementation for JavaFX applications. Say goodbye to using AWT's SystemTray icon, instead use a JavaFX Tray Icon.

FXTrayIcon Library intended for use in JavaFX applications that makes adding a System Tray icon easier. The FXTrayIcon class handles all the messy AWT

Dustin Redmond 248 Dec 30, 2022
A simple implementation of the Android In-App Billing API.

Google In-App Billing Library v4+ A simple implementation of the Android In-App Billing API. It supports: in-app purchases (both consumable and non-co

Moisoni Ioan 79 Dec 12, 2022
Implementation of ImageView for Android that supports zooming, by various touch gestures.

PhotoView PhotoView aims to help produce an easily usable implementation of a zooming Android ImageView. [ Dependency Add this in your root build.grad

Baseflow 18.4k Dec 30, 2022
FlexBoxFX is a JavaFX implementation of CSS3 flexbox.

FlexBoxFX is a JavaFX implementation of CSS3 flexbox layout manager

null 5 Nov 4, 2021
A java based course editor for the AutoDrive mod, works with both the FS19 + FS22 versions of the mod

Java Java version greater than 13 is required. JRE or JDK are both possible. Current Java versions can be downloaded here: https://www.oracle.com/java

null 47 Jan 1, 2023
Tic-Tac-Toe-GUI - This repository contains Java based interactive Tic-Tac-Toe game.

Tic-Tac-Toe This repository contains Java based interactive Tic-Tac-Toe game. In this game you can play individual or with another player with your na

Ahmed Hossam 11 Sep 1, 2022
A core java-based desktop application that can secretly track users' activities, record screenshots and keys typed by the user

@Abhishek Tandon @Manoj Kumar Dewangan @Ritesh Barik Introduction This project is a core java-based desktop application that can secretly track users'

Vaibhav Biturwar 0 Apr 2, 2022
FXDesktopSearch - a Java and JavaFX based Desktop Search Application

FXDesktopSearch - The free search application for your desktop FXDesktopSearch is a Java and JavaFX based Desktop Search Application. It crawls a conf

Mirko Sertic 162 Oct 14, 2022
DataFX - is a JavaFX frameworks that provides additional features to create MVC based applications in JavaFX by providing routing and a context for CDI.

What you’ve stumbled upon here is a project that intends to make retrieving, massaging, populating, viewing, and editing data in JavaFX UI controls ea

Guigarage 110 Dec 29, 2022
It is a desktop application based on JavaFX to implement a Carmeter-GPS.

CarMeter_JavaFX It is a desktop application based on JavaFX to implement a Carmeter-GPS. Video View more Details about the project.---> Link to Video

Abdullah HAnfy 0 Nov 29, 2022
This app displays the perceived strength of a single earthquake event based on the DYFI indicator.

This app displays the perceived strength of a single earthquake event based on the DYFI indicator. Used in a Udacity course in the Android Basics Nanodegree.

Ezaz Ahammad 1 Jan 23, 2022
JavaFX based Connect4 Game.

Connect4 [email protected] https://github.com/MitchellGray100/Connect4 JavaFX Connect4 Game. Local 2 Player or 1 Player (With AI). It's Connec

Mitchell Gray 3 Jan 6, 2022
null 4 Oct 21, 2022
Utilizando do Java swing e do banco de dados MySQL, criei esse projeto com intuito de práticar a conexão do Java com MySQL e as janelas do Java swing

MeusCursos.com Meu primeiro projeto sozinho Utilizando do Java swing e do banco de dados MySQL, criei esse projeto com intuito de práticar a conexão d

João Vitor Ferreira Peixoto 1 Apr 2, 2022
Everything I code in java / Learn in Java I will post here to show my Progress :)

This repository contains all the codee i have written or used to help me learn This is going to be a repository that holds the source files for codene

unofficialdxnny 2 Jan 10, 2022
A Java framework for creating sophisticated calendar views (JavaFX 8, 9, 10, and 11)

CalendarFX A Java framework for creating sophisticated calendar views based on JavaFX. A detailed developer manual can be found online: CalendarFX 8 D

DLSC Software & Consulting GmbH 660 Jan 6, 2023
Controls for adding Parallax effects for Java (JavaFX)

FXParallax Parallax framework for Java (JavaFX). This framework adds controls to add Parallax effects to JavaFX application, this effect can add a sen

Pedro Duque Vieira 36 Sep 30, 2022