BuiltWithNOF
Application in J3D

Unfortunately the realization of a complete CSG architecture is not easy. In fact this involves complex computation of region of intersection between primitives and then the extraction of the new object surfaces. In the attempt of obtaining an immediate visibile we implemented result the only sum operation, leaving at a second time the opportunity to complete the work inserting also the complementation, difference and intersection operations.
The sum implementation in Java3D has been accomplished in the easiest way possible, that is drawing the objects to be summed one after the other, without deepening about their intersection regions.
Fortunately Java3D already offer a support to multiple transformation  (translations and rotations) of object groups, performing also an optimization process.
In particolar is possibile to see every object in our xml document as a transformation group (TG), that is a transformation matrix (translation and rotation) to which we append (exiting arrow) the effective object, that in our case can be either a primitive or a sum of other objects.
On the other hand, sum can be mapped in a branch group (BG), which takes to (exiting arrow) all the objects (that are transformation group) that compose the sum. This architecture can continue indefinetely till the reaching the tree leaves, that are the primitives. Java will proceed automatically
optimizing where possibile this tree, in particolar combining all transformations that lead to a leaf in a single transformation.

 

Therefore, the second step we have to take is to map our XML document in this Java3D structure.
One of the advantages of choosing an XML architecture is the chance to exploit some tool (already present) for validation and elaboration of the input file
Java already includes the Apache Xerces parser which implements SAX APIs, to validate the file (so there will not be need of control about the grammatical correctness of the input document) and to generate events during the parsing at every tag recognising. These events can be managed by the programmer asseciating them with different methods.
To all possibile tags (in our case objectType, sum, box, relativePosition, etc.) will correspond the build, update and clean methods.
In details:
- at an opening tag a build method is called. It receives as arguments the tag attributes (i.e., in the case of the cylinder, y and radius) and the tag father, that is the last not already closed tag encontered before the opening of this new one.
- when a “son” tag completes, it will send its results to its father. This is possible by means of update method. The son need to keep the father reference received at its opening to send correctly the results. Depending on the received type by the son, the father can couple different update methods.

- at the closing tag a clean method is called. As we said, clean takes care of completing and sending its results to the father (calling the father method update, visible by means of an interface) and, usually, finalizing the variables.
Let see now how the methods were implemented for each tag
relativePosition
Relative Position is a tag of TransformationType type, and was already implemented before our work. At its creation it builds up a transformation group with the characteristics given by its attributes, and at its (prompt) closure sends the TG reference to its father
Object
Considering that complementation is not implemented, we can find in each tag object (that is the space between tag opening and closure) either a primitive or a sum, followed by a transformation. Therefore the transformation group creation simply takes place adding the object received by the first son (no matter is a primitive or a BG) to the TG received from relativePosition.
The knot of this tag is to send the result to the right father: in fact, in the case of nested objects, there can be more than one object tag already open, each of them with a different father. Therefore the build method must save in a stack, and not in a single variable, the father reference. In this way, the method clean will know it has to refer to the father at the top of the father stack. Given the update command, it will update the stack removing the just used father reference. In this way the outer object can reobtain the reference to his own father.
Sum
In the sum case too the recursion causes nested sum tags. But in this case the problem is not the father reference, which is always the same (object), but the correct construction of the Branch Group. In fact sum must be able to create more than one BG at the same time in the nested sum case.
I.e., in the picture above in this page, the cone with its transformation must not be attached to the highest BG, which is still open, but to the one whose is actually son.
Also in this case, this is possibile by means of a stack.
At the opening tag, the build method creates a new BG and saves it at the top of a stack.
Every time a son (in our case, always an object) sends a TG, this is appended to the BG which is at the top of the stack in that moment. In this way, if there is a recursion, the TG is correctly appended to the outer BG
The clean method sends the obtained BG (the one at the top of the stack) to the father and updates the stack.
The primitives
The primitive accomplishment was achieved in a very simple way, using the four primitives already present in Java3D, and halfing the values of the box (since Java3D doubles the dimensions considering the inserted values both in the positive and in the negative axis direction) as single trick.
The appereance is set by default to blue color, but in the future we want to make possibile to specify the color (and, eventually, the texture too) for each primitive, which will cause a little modify to the XML schema.

[Home] [Introduction] [The Goals] [CSG] [Our Work] [Application in J3D] [XML Schema] [Results] [Links]