lizhao21st / jsc3d

Automatically exported from code.google.com/p/jsc3d
0 stars 0 forks source link

multiple stl view #52

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Hello, I would like to load multiple stl files on a scene.
I also wants to set the color of each models.

I saw this issue : https://code.google.com/p/jsc3d/issues/detail?id=36
But I didn't found a working example.

Here is my code (it loads only one model) :

<!DOCTYPE HTML>
<HTML>
<HEAD>
    <TITLE>JSC3D Demo</TITLE>
    <script type="text/javascript" src="jsc3d/jsc3d.js"></script>
    <script type="text/javascript" src="jsc3d/jsc3d.webgl.js"></script>
    <script type="text/javascript" src="jsc3d/jsc3d.touch.js"></script>
</HEAD>

<BODY>
    <div style="width:490px; margin:auto; position:relative;">
        <canvas id="cv" style="border: 1px solid;" width="400" height="300">
            It seems you are using an outdated browser that does not support canvas :-(
        </canvas>
    </div>

    <script type="text/javascript">
    var canvas = document.getElementById('cv');
    var viewer = new JSC3D.Viewer(canvas);

    var components = ['stl/dragon.stl', 'stl/cow.stl'];
    var theScene = new JSC3D.Scene;
    var numOfLoaded = 0;

    var onModelLoaded = function(scene) {
        var meshes = scene.getChildren();
        for (var i=0; i<meshes.length; i++) {
            theScene.addChild(meshes[i]);
        }
        if (++numOfLoaded == components.length)
            viewer.replaceScene(theScene);
    };
    for (var i=0; i<components.length; i++) {
        var loader = new JSC3D.StlLoader;
        loader.onload = onModelLoaded;
        loader.loadFromUrl(components[i]);
    }

    viewer.setParameter('ModelColor', '#FF0000');
    viewer.setParameter('BackgroundColor1', '#E5D7BA');
    viewer.setParameter('BackgroundColor2', '#383840');
    viewer.setParameter('Renderer', 'webgl');
    viewer.init();
    viewer.update();
    </script>

</BODY>
</HTML>

Thanks a lot.

Original issue reported on code.google.com by nathap...@gmail.com on 16 Dec 2013 at 4:39

GoogleCodeExporter commented 9 years ago
Your code is basically correct. In my own test, both models are loaded without 
error. The problem is one model is so large that it completely enclose the 
other. JSC3D does not support additional transformations for each mesh, so 
multiple models form different sources can be used in a scene only if they are 
positioned and scaled properly in the same space to work together.

Changing model color is rather easy. Just create a new material for each mesh 
with the colors wanted, then set them to corresponding meshes through the 
JSC3D.Mesh.prototype.setMaterial() method. See the following snippet:

  ...
  // this changes the model color to red
  mesh.setMaterial(new JSC3D.Material('red-material', 0, 0xff0000));
  ...
  viewer.update();
  ...

Original comment by Humu2...@gmail.com on 16 Dec 2013 at 6:46

Attachments:

GoogleCodeExporter commented 9 years ago
Thanks a lot ! Indeed I thought my models had the same size. So it works ! :-)

I'm trying to set colors on my models. I added your snippet in the 
onModelLoaded function, using a color array :

var colors = [0xff0000, 0x0000ff, 0x00ff00, 0xffff00, 0x00ffff];

var onModelLoaded = function(scene) {
   var meshes = scene.getChildren();
   for (var i=0; i<meshes.length; i++) {
      theScene.addChild(meshes[i]);
      meshes[i].setMaterial(new JSC3D.Material('red-material', 0, colors[i]));
   }
   if (++numOfLoaded == components.length)
      viewer.replaceScene(theScene);
};

But all models are red...
I missed something ?

Original comment by nathap...@gmail.com on 16 Dec 2013 at 11:50

GoogleCodeExporter commented 9 years ago
The onModelLoaded callback will be invoked each time a new model is coming. Its 
implementation should be changed slightly:

  var onModelLoaded = function(scene) {
    var meshes = scene.getChildren();
    // there should be only one mesh for an STL
    if (meshes.length > 0) {
      meshes[0].setMaterial(new JSC3D.Material('red-material', 0, colors[numOfLoaded]));
    }
    if (++numOfLoaded == components.length)
      viewer.replaceScene(theScene);
  };

The new one will be ok.

Original comment by Humu2...@gmail.com on 17 Dec 2013 at 3:17

GoogleCodeExporter commented 9 years ago
Thanks for your answer.
Unfortunately it doesn't work with this code. Nothing apperas on the view.

I attached my test code, feel free to try it.

Original comment by nathap...@gmail.com on 17 Dec 2013 at 8:06

Attachments:

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Problem solved !
This code works :

var onModelLoaded = function(scene) {
   var meshes = scene.getChildren();
   // there should be only one mesh for an STL
   for (var i=0; i<meshes.length; i++) {
      theScene.addChild(meshes[i]);
      if (meshes.length > 0)
         meshes[0].setMaterial(new JSC3D.Material('red-material', 0, colors[numOfLoaded]));
   }
   if (++numOfLoaded == components.length)
      viewer.replaceScene(theScene);
};

I sugest to add instructions about multiple stl loads and colors in getting 
started section, because it's very useful !

Original comment by nathap...@gmail.com on 17 Dec 2013 at 8:26

Attachments:

GoogleCodeExporter commented 9 years ago
Nice! Thanks for your suggestion!

Original comment by Humu2...@gmail.com on 18 Dec 2013 at 2:06

GoogleCodeExporter commented 9 years ago
You're welcome !
Hmm, I have last question : Is it possible to load displays each file as soon 
as it's loaded ? Currently, the files are displayed simultaneously.

Original comment by nathap...@gmail.com on 18 Dec 2013 at 8:55

GoogleCodeExporter commented 9 years ago
Yes of course. Instead of waiting for all models to be ready, this time just 
create the scene object as the 1st model is done. Then add the model to the 
scene and pass the scene to viewer. For each model other than the 1st one, when 
it's loaded completely, add it into the current scene, whose bounding box 
should then be updated manually:

  // when a new mesh is coming
  ...
  mesh.init();
  theScene.addChild(mesh);
  theScene.calcAABB();
  viewer.update();
  ...

The scene.calcAABB() method computes the new bounding box of an existing scene. 
This is necessary to ensure a correct rotation pivot.

Original comment by Humu2...@gmail.com on 18 Dec 2013 at 12:28

GoogleCodeExporter commented 9 years ago
Hello,
A question to build onto the original problem.  I am trying to load multiple 
stl files in a scene, with multiple scenes / canvases on the page.
If I code each scene separately, as you wrote above, then everything works 
fine.  However, the ideal would be to have the whole thing run off a counter, 
creating x scenes as needed.  When I do this there are two issues I run into.

First, this code runs through the counter in the first alert and then moves to 
the "onModelLoaded" section, where j is undefined.  How can I get j to carry 
through to the "onModelLoaded" section.

Second, In defining the "components" array as components[1] = 1,2,3 and 
components[2] = 4,5,6 they are actual loaded as scene1=1,2,3 and scene2=5,4,6.
I'm not sure if this is related to the "onModelloaded" section or the "loader" 
section.  For the "loader" section the behavior is the same whether it is in a 
for loop (j) or hard coded.

Thanks for any help you can provide.

Original comment by madb...@gmail.com on 9 Jul 2014 at 9:09

Attachments: