x3dom / x3dom

X3DOM. A framework for integrating and manipulating X3D scenes as HTML5/DOM elements.
http://x3dom.org
Other
813 stars 271 forks source link

The rendering of objects, which is done with extrusion not as expected #1268

Closed AxelGHC closed 1 year ago

AxelGHC commented 1 year ago

With the use of follow code as an example:

<html>              
    <head>               
        <meta http-equiv='X-UA-Compatible' content='IE=edge'/>              
        <title>Test</title>                 
        <script type='text/javascript' src='https://x3dom.org/download/dev/x3dom-full.js'> </script>  
        <link rel='stylesheet' type='text/css' href='https://www.x3dom.org/download/x3dom.css'/>                 

        <style >
        </style>
        <script>
        </script>
    </head>              
    <body> 
        <x3d id="canvas">             
            <Scene DEF='Scene'> 
                <Shape >       
                    <Appearance>   
                        <Material diffuseColor='0.906 0.902 0.906' transparency='0.9'></Material>   
                    </Appearance>  
                    <Extrusion  crossSection='0 0 0 7 3.5 7 3.5 8 2.5 8 2.5 7 0 7 0 7 15.5 7 15.5 9 10.5 9 10.5 7 0 7 0 9 9 9 9 11 7 11 7 9 0 9 0 12 16 12 16 0 0 0 ' spine='0 0 0 0 0.5 0' />   
                </Shape>  

            </Scene>
        </x3d> 
    </body>              
</html> 

was expected an object like a Cuboid with three windows how shown in the follow:

image

In the browser only two windows are open:

image

I am new here and hope to placed my problem right. I am grateful for any suggestions.

Best regards Axel.

andreasplesch commented 1 year ago

https://gist.githack.com/andreasplesch/f52e4b949b8b99fb04c90a04a1959242/raw/84ec58900da3f8d4be82d9ebf304c6aa8480efb6/x3dom-extr-nocap.html

has the begin and endCaps turned off.

There is no way to have holes in the cross-section curve. You would need to construct the mesh with an IndexedFaceSet.

One can construct pseudo-holes:

https://gist.githack.com/andreasplesch/f52e4b949b8b99fb04c90a04a1959242/raw/388363b0d8d6e3d93cd08e4ad3a5ffa11f6cc126/x3dom-extr-nocap.html

This extrusion has another order of points with repetition to give the algorithm a chance.

x3dom is using the earcut libray to triangulate the cross-section for the caps: https://github.com/mapbox/earcut

But other x3d viewers may use other algorithms, so for complex topologies it is most robust to construct the mesh with other tools such as meshlab.

AxelGHC commented 1 year ago

Hi Andreas,

I will have a look at IndexedFaceSet. My goal is to find an algorithm that will allow me to display such openings as easily as possible. The Openings can be complex (not overlapping but different places). Now I am looking for an easy to understand example.

The easiest way for me seems to be boolean operations like difference. These do not exist in x3dom as far as I know.

Thanks for your quick reply Axel.

andreasplesch commented 1 year ago

No, x3d does not have CSG. But see

https://observablehq.com/@andreasplesch/constructive-solid-geometry-with-jscad-and-x3dom

AxelGHC commented 1 year ago

Thanks for the link. I like what I have seen very much. Now I have started to build a simple example:

I have build one only with two boxes:

<html>              
    <head>               
        <meta http-equiv='X-UA-Compatible' content='IE=edge'/>              
        <title>Test</title>                 
        <script type='text/javascript' src='https://x3dom.org/download/dev/x3dom-full.js'> </script>  
        <link rel='stylesheet' type='text/css' href='https://www.x3dom.org/download/x3dom.css'/>                 

        <style >
        </style>
        <script>
        </script>
    </head>              
    <body> 
        <x3d id="canvas">             
            <Scene DEF='Scene'> 
                <Shape >       
                    <Appearance>   
                        <Material diffuseColor='0.906 0.902 0.906' transparency='0.9'></Material>   
                    </Appearance>  
                    <box size = '1 2 0.5'></box> 

                    <!-- difference() {
                    cube([1,2,0.5],true);
                    cube([0.5,1,0.6],true);} -->

                </Shape>  
                <Shape >       
                    <Appearance>   
                        <Material diffuseColor='0 0 1' ></Material>   
                    </Appearance>  
                    <box size = '0.5 1 0.5'></box> 
                </Shape>  
            </Scene>
        </x3d> 
    </body>              
</html> 

I have noted the simple difference as a comment.

Unfortunately, I could not figure out how to insert this in place of the two boxes, so that it is also displayed as a difference in the browser.

andreasplesch commented 1 year ago

You could also consider using jscad for visualization directly. It includes a simple renderer.

For x3dom the approach would be:

Construct the geometry (boolean operations) with jscad.

Convert the geometry with jscad x3d-serializer. It will produce a full scene in xml. The geometry will be an IndexedTriangleSet. You can extract the IndexedTriangleSet from the xml string with js regex or string functions. Or you can use a DomParser (see MDN) to convert the xml to a dom document, and then use x3ddocument.querySelector('IndexedTriangleSet') to extract the geometry as a DOM element.

Finally replace the placeholder geometry in your x3dom scene with the extracted geometry, using dom methods.

You will need to understand js manipulation of html documents. MDN is a good start to learn.

Hope this helps.

AxelGHC commented 1 year ago

Thanks for the quick reply. Unfortunately, the proposed path does not fit into the previous process. I have tables in Excel that describe the position, dimensions, colors and transparency of objects. From this an html file is created with VBA, which use box, cone and sphere. Many x3dom functions are applied to the x3d tags. The issue described at the beginning led me away from the primitives for the first time.

It turns out that I can't find the order of points with repetition to give the algorithm a chance. If I pursue this further, I need to find a way to incorporate jscad's conversion function to x3dom in VBA.

This is a new story. So I will close the issue now and hope it will help others. Thanks to Andreas.

andreasplesch commented 1 year ago

Ok, understood.

You would need to use node.js and probably the jscad commandline interface to process a jscad design (from a .jscad file) and export to x3d. Then you can use VBA to extract the geometry from the x3d and place it into the html.

Here are two more ideas.

Consider using python to generate the HTML. There is a python api for the excellent meshlab software:

https://pymeshlab.readthedocs.io/en/latest/filter_list.html#generate_boolean_difference https://pymeshlab.readthedocs.io/en/latest/io_format_list.html#save-mesh-parameters

There is probably an Excel python api as well, or just use csv.

Freecad would be another good python option. You could use the gui to figure out the process and then fully script it. It can export to x3d:

https://wiki.freecad.org/Import_Export

Another idea is to go back to step 1 and construct an IndexedFaceSet yourself with VBA. You would need to create the polygons/triangles for the primitives manually which may be possible, perhaps by using templates. If the distribution of primitives and holes is very general, it becomes difficult. That is why there is sophisticated software for that.