Volume patterns

Discussion in 'ShapeJS' started by Mowi, Dec 8, 2013.

  1. Mowi
    Mowi Member
    Last edited: Dec 8, 2013
  2. AlanHudson
    AlanHudson Shapeways Employee Dev Team
    You can create your own DataSource as in this example sphere:

    importPackage(Packages.abfab3d.util);

    var radius;

    var Sphere = {
    getDataValue : function(pnt, data) {
    var x = pnt.v[0];
    var y = pnt.v[1];
    var z = pnt.v[2];

    var vs = pnt.getScaledVoxelSize();

    var r = r = Math.sqrt(x*x + y*y + z*z);
    data.v[0] = MathUtil.step10(r, radius, vs);

    return DataSource.RESULT_OK;
    }
    };

    function main(args){
    radius = 5*MM;
    var a = radius*1.1;
    var voxelSize = 0.1*MM;

    var dest = createGrid(-a,a,-a,a,-a,a,voxelSize);

    var maker = new GridMaker();
    maker.setSource(Sphere);
    maker.makeGrid(dest);

    return dest;
    }


    A data source calculates: The way to fill the voxel grid is to create an object with a DataSource interface, which can calculates a signed distance function for each point in space. This object is fed to an instance of GridMaker which controls the calculations. The distance function calculations may be very complex task for complex object. But this calculation can be simplified by composing complex object from many simpler one using several simple operations. I feel like I developed some more complex volume patterns but this is the best example I can find at home. I'll check at work tomorrow and see if I have better ones.
     
  3. Hello. I've tried to modify the above example for creating a sphere with given radius. But it returns an empty scene. Could you point where I am wrong? What is the right way implementing the DataSource interface with parameters?
    Here is the code:
    Code:
    importPackage(Packages.abfab3d.util);
    
    function MySphere(radius) {
      this.radius = radius;
      this.getDataValue = function(pnt, data) {
        var x = pnt.v[0];
        var y = pnt.v[1];
        var z = pnt.v[2];
        var vs = pnt.getScaledVoxelSize();
        var r = Math.sqrt(x*x + y*y + z*z);
        data.v[0] = MathUtil.step10(r, this.radius, vs);
        return DataSource.RESULT_OK;
      };
    }
    
    function main() {
      var radius = 5*MM;
      var a = radius * 1.2;
      var grid = createGrid(-a,a,-a,a,-a,a, 0.1*MM);
      var maker = new GridMaker();
      maker.setSource( new MySphere(radius) );
      maker.makeGrid(grid);
      return grid;
    }
    
     
    Last edited: Jan 3, 2014
  4. AlanHudson
    AlanHudson Shapeways Employee Dev Team
    Sadly I remember trying to get that to work when I coded the example. I couldn't figure it out. I'm not a big Javascript expert so likely I'm missing how it defines things to make this happen. I punted and just made the variable global which worked but sucks. Please tell me if you figure it out. I'll try to ping the web developers around here and see if they can figure it out.
     
  5. This is really strange for me. If I replace this line:
    Code:
    data.v[0] = MathUtil.step10(r, this.radius, vs);
    with this:
    Code:
    data.v[0] = MathUtil.step10(r, 5*MM, vs);
    it works. This is a mystery for me, since I tried to verify that "this.radius" actually gets the right value (with some exception message throwing). So yes, it is.
     
  6. AlanHudson
    AlanHudson Shapeways Employee Dev Team
    I suspect some sort of typing problem. Ie if radius was the string "2.0" it would still print as 2.0 That said I can't really understand from the example how that could be. Javascript has some funny type mechanisms. Perhaps try printing its type:

    Object.prototype.toString.call(this.radius)

    Seems there is not instanceof operator but this post provides some suggestions:

    http://stackoverflow.com/questions/332422/how-do-i-get-the-n ame-of-an-objects-type-in-javascript
     
  7. MrNib
    MrNib Well-Known Member
    So I'm trying to wrap my brain around this ShapeJS thing and how or why I would use it. I've recently been playing with the Tinkercad scripting to generate parametric objects and I assume I should be able to do similar things here. I suppose it's basically a matter of revisiting the code and adapting it.

    The Tinkercad scripting allows you to generate polygons on a mathematically defined shape and then send all the polygons to a library routine that generates the solid object you can export or further edit in their editor. I'm not sure if you can do Boolean operations in the Tinkercad scripting but I assume it's there if I wade into it more. For example, I thought I was super hot stuff after creating a cylinder with a pattern height defined by theta and Z parameters:

    thetaZcylinder.jpg

    So I'm thinking I could do this type of thing here to generate parametric items, except with the voxel mechanism, and eventually generate some app to let users generate their own custom patterned products. I'm not experienced in the whole app writing/hosting/store interfacing thing so I also don't see a clear path forward if I wanted to leverage Shapeways capabilities for doing this sort of thing. Am I barking up the wrong tree?
     
  8. AlanHudson
    AlanHudson Shapeways Employee Dev Team
    [qoute]
    So I'm thinking I could do this type of thing here to generate parametric items, except with the voxel mechanism, and eventually generate some app to let users generate their own custom patterned products. I'm not experienced in the whole app writing/hosting/store interfacing thing so I also don't see a clear path forward if I wanted to leverage Shapeways capabilities for doing this sort of thing. Am I barking up the wrong tree?[/quote]

    Your barking up the right tree but the tree is not totally grown yet. Our intent is to make a system you can prototype creators and then deploy them as as real applications. Our focus will be on voxel applications not triangles.

    Currently you can implement some nice creators. But the point where it all get's deployed to others is not as well developed. Currently you could deploy something if you deploy your own Java instance or use these php examples: https://github.com/Shapeways/ShapeJS-Example.

    If you haven't seen this page take a look at some example scripts we made: https://shapejs.shapeways.com/examples?li=dh_examples

    We've done one full day deep dive on the language and should be having a West Coast version soon as well.

     
  9. MrNib
    MrNib Well-Known Member
    Ok, not being a software guru that material will require lots of study!
     
  10. AlanHudson
    AlanHudson Shapeways Employee Dev Team
    One of the things we are trying to do is get this to the point that a Javascript developer who understands 3D concepts can make their own creator. It will require some layers of hiding the server and user-interface tasks to get there. One of the key issues is how much server resources a creator takes. Ie that compute time costs money on the backend and its pretty easy to make creators that use a bunch of computer time if not optimized. Maybe the solution is just a maximum cap that we'll execute.
     
  11. MrNib
    MrNib Well-Known Member
    The github link mentioned above doesn't seem to be valid.

    In my tender novice state if I were to try and duplicate my bumpy cylinder example there may be a few ways to do that.

    1) Create it directly as a datasource using the appropriate (theta,Z) equations that apply voxels to points in space into the x,y,z grid.

    2) Warp or transform a cylinder datasource with offsets determined by vectors generated by those same equations.

    3) Apply the pattern to a cylinder using the cylinder wrap function using an x-y expression of the pattern from a generated vector file or external bitmap (like the ring creator).

    Am I still barking up the right tree? In the long run to make a useful creator the idea would be to input an equation that the routine would use to generate the surface pattern. That's my next step in Tinkercad so I can have one custom script instead of one script for each individual equation. I assume that would also be possible here.
     
  12. MrNib
    MrNib Well-Known Member
    Well things are not as dark as they seem. I hacked the sphere example from above to generate a ribbed cylinder, with rib movement in the Z-dimension. It definitely takes fewer lines of code to generate than what you need to do when defining individual polygons. Not sure how to also get variations in theta at this point. Maybe it requires a new equation or a completely different generation mode.

    ribbed_cylinder.jpg

    In that example code it's not clear where in the world the "pnt" data object is defined, what's in it, or where it is coming from. Sadly my memories of C++ and Matlab are no longer fresh in my brain so some things are recognizable but not completely familiar.
     
  13. GambaLabs
    GambaLabs Member
    I made a "rounded star" creator, maybe you will find it helpful (attached).
     

    Attached Files:

  14. Ok,
    Back from a while :)
    I have managed to work around the issue I've pointed above (parameterized object creation). The following code works:

    Code:
    importPackage(Packages.abfab3d.util);
    
    function makeSphere(radius)
    {
    	var sphere = {
    		getDataValue: function(pnt, data) 
    		{
    			var x = pnt.v[0];
    			var y = pnt.v[1];
    			var z = pnt.v[2];
    			var vs = pnt.getScaledVoxelSize();
    			var r = Math.sqrt(x*x + y*y + z*z);
    			data.v[0] = MathUtil.step10(r, radius, vs);
    			return DataSource.RESULT_OK;
    		}
    	};
      return sphere;
    }
    
    
    function main() {
      var radius = 5*MM;
      var a = radius * 1.2;
      var grid = createGrid(-a,a,-a,a,-a,a, 0.1*MM);
      var maker = new GridMaker();
      
      maker.setSource( makeSphere(radius) );
      maker.makeGrid(grid);
      return grid;
    }
    
    Well. It will indeed draw a sphere. A problem arises when we try to transform it. Javascript would complain that there is no setTransform method for this type of object. Here is my next workaround: Just wrap the newly created object in the DataTransformer object:
    Code:
    importPackage(Packages.abfab3d.util);
    
    function makeSphere(radius)
    {
    	var sphere = {
    		getDataValue: function(pnt, data) 
    		{
    			var x = pnt.v[0];
    			var y = pnt.v[1];
    			var z = pnt.v[2];
    			var vs = pnt.getScaledVoxelSize();
    			var r = Math.sqrt(x*x + y*y + z*z);
    			data.v[0] = MathUtil.step10(r, radius, vs);
    			return DataSource.RESULT_OK;
    		}
    	};
      var sphereDataTransformer = new DataTransformer();
      sphereDataTransformer.setSource(sphere);
      return sphereDataTransformer;
    }
    
    
    
    function main() {
      var radius = 8*MM;
      var a = radius * 1.2;
      var grid = createGrid(-a,a,-a,a,-a,a, 0.1*MM);
      var maker = new GridMaker();
      var s = makeSphere(radius);
      s.setTransform( new Translation(5*MM,0,0) );
      maker.setSource(s);
      maker.makeGrid(grid);
      return grid;
    }
    
    Hope someone would find it useful, and maybe point an easier/ more correct way of doing this.
     
    Last edited: Mar 24, 2014
  15. MrNib
    MrNib Well-Known Member
    I got things to work with Alan's initial approach and the global variables. Problem for me was that I needed more variables than just a radius to define equation based patterned elements. I couldn't figure out how to pass more variables to the function without catastrophe (although it should be simple) or something else bad was happening. Anyway, I can make things more elegant with real functions later after I demonstrate the basics. The present problem I'm having is that anything in excess of the ninth text box input variable does not seem to provide a valid usable number. I suppose I could pull different numbers out of an input string of several cascaded numbers but that doesn't seem like a lot of fun. Is there any way to display values of variables being used by these scripts to help with debugging?

    patterned_tube_trial.jpg
     
  16. GambaLabs
    GambaLabs Member
    You can use the JSON standard to pack together several arguments in a single input string, I think it's not that bad.

     

    Attached Files:

  17. MrNib
    MrNib Well-Known Member
    That's a good thing to know. Thanks!
     
  18. jpitkin
    jpitkin Member
    Is there a way to convert an STL file to a custom datasource?
     
  19. AlanHudson
    AlanHudson Shapeways Employee Dev Team
    yes, you can turn any grid into a datasource with DataSourceGrid. So you load the STL into a grid



    So this type of code would load up several STL's into a grid:

    var union = new Union();
    union.add(new DataSourceGrid(load("part_01.stl",voxelSize)));
    union.add(new DataSourceGrid(load("part_02.stl",voxelSize)));

    var maker = new GridMaker();
    maker.setSource(union);

    Of course you just said the word custom data source which maybe has more too it. Does this answer your question?
     
  20. jpitkin
    jpitkin Member
    I should have been more clear. What I am trying to do is embed a complex custom shape within the javascript code, so that I don't need to use the load command or require any user inputs. Does that make sense?