mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
99.31k stars 35.12k forks source link

ExtrudeGeometry #323

Closed mrdoob closed 12 years ago

mrdoob commented 12 years ago

I was wondering if the extrude part of TextGeometry could be somehow separated into it's on ExtrudeGeometry class.

Right now we have have LatheGeometry which gets a set of points and creates a revoluted mesh with it, and would be great to have something like that for extrusions.

@zz85, @alteredq, thoughts?

SolarCoordinates commented 12 years ago

You mean extrude a polygonal face, like this? ( http://www.youtube.com/watch?v=SGHWh9ON4HA )

I had plans to make this already, so if you want to give me a few days, perhaps I could save you the trouble.

If the face is planar (i.e. all vertices lie within the same plane,) it should just be a matter of making a duplicate of the vertices, and connecting the duplicates to both the original vertices and also their adjacent duplicates, e.g.:

original: (D)--A--B--C--D--(A)
               |  |  |  |    
               |  |  |  |      <-- length of the extrusion; orthogonal to the (ABCD) plane
               |  |  |  |    
          (D')-A'-B'-C'-D'-(A')
mrdoob commented 12 years ago

That's also nice!

I meant something like this though: http://www.youtube.com/watch?v=xfpRrui4Kc4

SolarCoordinates commented 12 years ago

Hmm... very similar, except you're starting with a line/spline instead of a face. You've got an extra step in there (making a poly face that's a close approximation of the line/spline) before extruding it to make it 3-dimensional.

mrdoob commented 12 years ago

Yup. Which, if I'm not mistaken, it's exactly what TextGeometry is doing.

alteredq commented 12 years ago

Maybe, if we could create API wrapping up font glyph format to be able to construct arbitrary shapes (instead of just pre-defined font glyphs loaded from a file).

This seems like a pretty powerful system, using series of straight and curved line segments to define vector shapes:

https://github.com/mrdoob/three.js/blob/master/src/extras/geometries/TextGeometry.js#L849

https://github.com/mrdoob/three.js/blob/master/examples/fonts/helvetiker_regular.typeface.js

Extrusion itself is pretty straightforward, what's messy is triangulation of arbitrary polygons, especially holes make problems.

zz85 commented 12 years ago

Sounds good... this was what I thought too of working on the text but haven't gotten to abstract it. I was thinking an object which encapsulates a shape plane and then feeding the shape to the extruder.

Are you thinking along the lines of this?

shape = new THREE.Shape2D();
// internally store the paths. also called the line in the maya video
shape.moveTo(0,0);
shape.lineTo(10,10);
shape.bezierTo(20,20,20,20);
shape.quadBezierTo(30,30,30,30,30,30);
// thats what my code can potentially support right now, 
// but it'd be cool if it supports c-splines or other curves too
// (looks like maya uses cardinal spline?)
extruded = new THREE.ExtrudeGeometry(shape, amount, options);

Although, I'm not too sure what ExtrudeGeometry could be use with other than planes.

Extruding faces from polygons (like the first video and sketchup) would be really cool too, but implementation might be slightly different for that too...

mrdoob commented 12 years ago

Perhaps that's a bit too much... I think it's good enough to have an Array of vectors.

extruded = new THREE.ExtrudeGeometry( [ new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 1, 1, 0 ), ... ] /*points*/, 100 /*amount*/, 10 /*steps*/ );
alteredq commented 12 years ago

@zz85 Yes, I was thinking about something like this.

@mrdoob I know, just this functionality is somehow already in TextGeometry, zz85 did great job with fonts, they are full vector shapes.

It's very tempting to abstract it for something more powerful (you would get arbitrary vector shapes with user selectable tessellation).

Using just a list of points would be using just a smaller subset of TextGeometry capabilities.

zz85 commented 12 years ago

@mrdoob i see, but that might only work only for simple shapes without holes? to me, it seems that extrude should work on area/faces instead of points.

Would you be planning to utilize ExtrudeGeometry for TextGeometry?

zz85 commented 12 years ago

@alteredq yup we get the same thinking again the same time before reading each other's comments :)

alteredq commented 12 years ago

@zz85 ;)

@mrdoob A small example of what's possible already now, why it's tempting to be able to reuse full-force of TextGeometry pipeline (alphanumeric characters are just a small subset of possible shapes):

http://alteredqualia.com/three/examples/webgl_text.html#D81F0A2111#%E2%88%9E%E2%89%88%C2%B6%E2%80%A0%E2%84%A6%E2%89%A0%C2%A4%C3%A6%C2%AE%E2%80%A1

Maybe we even wouldn't need full-fledged API for 2d shapes, maybe if we could just pass in strings like they are in JS font definitions. In such way there could be for example simple library of interesting procedural 2d shapes.

zz85 commented 12 years ago

Perhaps I could try explaining my point better with some code.. see

https://gist.github.com/1065179

We could create shape using the familiar 2d canvas api with the Shape/Path object or we could also import points like

var shape = new THREE.Shape();
shape.importFromPoints([ new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 1, 1, 0 ), ... ]/*points*/);
extruded = shape.extrude(100 /*amount*/, 10 /*steps*/ );

Potentially, this shape class could be used for Text and Lathe.

In future, we could also use this shape class for more advance procedural modeling, eg. free-form extrusion using curved paths

zz85 commented 12 years ago

did we replied the same time again? ;) implementation-wise we could store the data in a json like typeface.js or do it overway, but i guess as shown in my sample code, should not be too difficult to do...

alteredq commented 12 years ago

Yes, Shape2D API looks neat ;).

mrdoob commented 12 years ago

@mrdoob i see, but that might only work only for simple shapes without holes? to me, it seems that extrude should work on area/faces instead of points.

True, I didn't considered holes...

Shape2D API looks good indeed, I would just call it Shape though. But, instead of shape.triangulate, shape.extrude I think I would still keep the separation like this (copy/pasting your code):

shape = new THREE.Shape();
shape.moveTo(0,0);
shape.lineTo(10,10);
shape.bezierTo(20,20,20,20);
shape.quadBezierTo(30,30,30,30,30,30);

extruded = new THREE.ExtrudeGeometry(shape, amount, options);

So, maybe, for triangulate one could just do this:

extruded = new THREE.ExtrudeGeometry(shape, 0, { back: false });

Would you be planning to utilize ExtrudeGeometry for TextGeometry?

Yeah, TextGeometry would then create a internal Shape and then use ExtrudeGeometry for the final geometry. Or... TextGeometry could become TextShape instead.

How does it sound?

zz85 commented 12 years ago

i'm thinking about this and thought that my previous shape api should be called Path and Shape (with holes) could be a subclass of Path. Path are more generic lines but Shapes are enclosed path objects.

yes, agreed Text should be refactored to use Shape - im facing tight schedule at work recently, so could this wait or would anyone like to try on this?

also, im not sure if triangulate should be done internally in Shape or Extrude, i might think that extrude could work on already triangulated surfaces...

zz85 commented 12 years ago

update Path + Shape API.

https://gist.github.com/1065179/55ac83868f92bafe1cd5de797443cf619775f93f

zz85 commented 12 years ago

one more thing.. the current TextGeometry is an extrusion of multiple shapes (1 character == 1 shape), do you want ExtrudeGeometry to be a extrusion of a single shape or allow extrusion of multiple shapes (takes in [] array of Shapes in constructor)

mrdoob commented 12 years ago

yes, agreed Text should be refactored to use Shape - im facing tight schedule at work recently, so could this wait or would anyone like to try on this?

It can wait, of course! My intention was just to create some dialogue about this and see how it would make more sense API wise.

https://gist.github.com/1065179/55ac83868f92bafe1cd5de797443cf619775f93f

Looks good! Instead of ACTIONS I usually name these COMMANDS. But that's just a personal preference.

one more thing.. the current TextGeometry is an extrusion of multiple shapes (1 character == 1 shape), do you want ExtrudeGeometry to be a extrusion of a single shape or allow extrusion of multiple shapes (takes in [] array of Shapes in constructor)

Mhh, maybe it'll be better to just allow 1 shape. So TextGeometry would call ExtrudeGeometry one time per character and then merge the geometry generated... ?

alteredq commented 12 years ago

Mhh, maybe it'll be better to just allow 1 shape. So TextGeometry would call ExtrudeGeometry one time per character and then merge the geometry generated... ?

I guess it would be better to test this: generic geometry merging via GeometryUtils is quite slow, I feel current multi-shape creation in TextGeometry is faster (as it does only things that are really necessary for this particular use case).

This could be a bottleneck for complex multi-shape objects, like having longer chunks of texts.

https://gist.github.com/1065179/55ac83868f92bafe1cd5de797443cf619775f93f

Looks good! Instead of ACTIONS I usually name these COMMANDS. But that's just a personal preference.

Looks good indeed. My personal preference would be ACTIONS, but COMMANDS are also fine ;).

yes, agreed Text should be refactored to use Shape - im facing tight schedule at work recently, so could this wait or would anyone like to try on this?

Don't worry, this is open source, we contribute when we can ;).

SolarCoordinates commented 12 years ago

Is there a working example of THREE.path or TextGeometry?

I got THREE.path to initialize, assigned values, added it to the scene, etc.. but it gave an error when I attempted to render it. I got it to render in a simple 2D environment, but that wasn't going to work -- no way for me to tell if the extrusion worked if I'm looking at an orthographic view, straight into the face.

I couldn't even get TextGeometry to start up for the most part. I tried to put together a basic scene with it... and failed! It didn't like return this.faces[this.face][this.weight][this.style]; in TextGeometry.js' getFace : function()

zz85 commented 12 years ago

@SolarCoordinates TextGeometry is already working - examples are webgl_geometry_text.html and cavas_geometry_text.html

THREE.path cannot be used in a 3d scene yet... it needs to be converted into a shape, triangulated and used with extrusion... they are currently done in TextGeometry but should be refactored to the new API.

@mrdoob Is there already have a system for model hierarchy in three.js? If so, I supposed a TextGeometry could hold a group of extruded shapes (which are 3d mesh) otherwise a extrudedGeometry could take in a group/array of shapes (done in current TextGeometry).

SolarCoordinates commented 12 years ago

@zz85 I did notice this ( https://github.com/mrdoob/three.js/blob/master/examples/canvas_geometry_text.html ), however, it doesn't seem to work for me. Going to the corresponding "working example page" ( i.e. the directory where all other examples are hosted, with the file name appended: http://mrdoob.github.com/three.js/examples/canvas_geometry_text.html ) yields a 404: Page does not exist! Read the Full Documentation

When I attempted to host the files on my own server, they error:

Error: this.faces[this.face][this.weight] is undefined Source File: http://www.solarcoordinates.com/three/js/threeNew.js ( up-to-date three.js ) Line: 442 ( offending code: getFace:function() { return this.faces[this.face][this.weight][this.style] } )

I was going to make an attempt at writing the extrudeGeometry code, but it appears I am unable to even get started. =/

zz85 commented 12 years ago

are there any other logged errors? you can check out the samples at http://alteredqualia.com/three/examples/webgl_text.html or http://jabtunes.com/labs/3d/canvas_geometry_text.html too...

you would need to include some typeface.js fonts for this to work too..

mrdoob commented 12 years ago

Is there already have a system for model hierarchy in three.js? If so, I supposed a TextGeometry could hold a group of extruded shapes (which are 3d mesh) otherwise a extrudedGeometry could take in a group/array of shapes (done in current TextGeometry).

Good idea! Yeah, hierarchy does work, needs some improvements but should be usable.

alteredq commented 12 years ago

@zz85 @mrdoob About hierarchies - it would be nice if this would be optional - single large geometry vs hierarchy of many smaller objects have different performance characteristics and are appropriate for different use cases.

@SolarCoordinates Try WebGL example:

https://github.com/mrdoob/three.js/blob/master/examples/webgl_geometry_text.html

Though canvas one should also work.

Some compatible fonts are also already included in three.js repo:

https://github.com/mrdoob/three.js/tree/master/examples/fonts

You need to have included any font variant you are going to use (in repo are just regular and bold variants, if you want italics, you would need to generate them yourself here http://typeface.neocracy.org/).

SolarCoordinates commented 12 years ago

Get ready to witness the worst hackjob ever posted on the web! (This was made using http://jabtunes.com/labs/3d/canvas_geometry_text.html )

http://www.solarcoordinates.com/three/canvas_geometry_text4.html (It's supposed to be California.)

This method is perhaps the wrong way of going about doing it, but what I did was fake a font glyph with a series of Vector2's:

var glyphArray=[];
glyphArray.push( new THREE.Vector2 (610, 320) );
glyphArray.push( new THREE.Vector2 (450, 300) );
glyphArray.push( new THREE.Vector2 (392, 392) );
glyphArray.push( new THREE.Vector2 (266, 438) );
glyphArray.push( new THREE.Vector2 (190, 570) );
glyphArray.push( new THREE.Vector2 (190, 600) );
glyphArray.push( new THREE.Vector2 (160, 620) );
glyphArray.push( new THREE.Vector2 (160, 650) );
glyphArray.push( new THREE.Vector2 (180, 640) );
glyphArray.push( new THREE.Vector2 (165, 680) );
glyphArray.push( new THREE.Vector2 (150, 670) );
glyphArray.push( new THREE.Vector2 (90, 737) );
glyphArray.push( new THREE.Vector2 (80, 795) );
glyphArray.push( new THREE.Vector2 (50, 835) );
glyphArray.push( new THREE.Vector2 (64, 870) );
glyphArray.push( new THREE.Vector2 (60, 945) );
glyphArray.push( new THREE.Vector2 (300, 945) );
glyphArray.push( new THREE.Vector2 (300, 743) );
glyphArray.push( new THREE.Vector2 (600, 473) );
glyphArray.push( new THREE.Vector2 (626, 425) );
glyphArray.push( new THREE.Vector2 (600, 370) );
glyphArray.push( new THREE.Vector2 (610, 320) );

var glyphString = "m " + glyphArray[0].x + " " + glyphArray[0].y + " ";
for ( var i = 1; i < glyphArray.length; i++) glyphString += "l " + glyphArray[i].x + " " + glyphArray[i].y + " ";

var myShape = new THREE.Path(glyphArray);

Outside of that, all you should have to do is (1) replace "Hello three.js! :)" with a single letter and (2) replace glyph.o with glyphString in THREE.FontText.js

Obviously this is EXTREMELY unpolished. It's "working," if you want to call it that, but I'm not sure if it'd be better to refine it or throw the "faking a glyph" method out altogether.

SolarCoordinates commented 12 years ago

PS: Regarding the extrusion of an array of faces, I know 3d software such as Autodesk Maya offer the option to keep the extruded faces connected if the original faces share vertices. For example, if you were to extrude three adjacent faces along the outside of a cylinder, instead of each facing jutting out on its own, creating three finger-like objects ( http://i.imgur.com/ZiY2q.png ), you have the option to keep the shared vertices together ( http://i.imgur.com/VGphg.png ).

Seems to me that this would be a good addition.

mrdoob commented 12 years ago

But that's extruding faces of an already formed geometry. I was talking about extruding a 2d path, better not to mix things up :)

SolarCoordinates commented 12 years ago

@mrdoob Gotcha... well, even though I am an amateur at best at this stuff, if all you want is a 2D path -> 3D mesh extrusion using the TextGeometry code (and zz85's API, of course), I should be able to get it done in ~48 hours. Seems all I need to do is turn my canvas_geometry_text4.html's brute-force glyph fakery into respectable code... modular, abstract, API-friendly, and all that fancy stuff.

mrdoob commented 12 years ago

Feel free to give it a try :)

SolarCoordinates commented 12 years ago

Well, I spent maybe 8 hours on drawing the 2D path onto a 3D canvas, mostly figuring out how everything worked from the TextGeometry.js file. After I got an idea of how it worked, I wrote a function to break the path array into an array of THREE.Line line segments, which were added as children to an Object3D, which was then returned out of the function and drawn to the scene.

The good news: It works.

The bad news: I looked through zz85's Path API once more and realized that I'd created almost an exact copy of his THREE.Path.getPoints(divisions) function, which constituted the bulk of the code. There goes 7 hours of my life, reinventing the wheel. :) Oh well, hopefully I learned something and am more familiar with three.js than when I started.

Anyways, here's the code:

path.js

/* Returns Object3D with line segments stored as children  */
THREE.Path.prototype.createPathGeometry = function(divisions, lineMaterial) {
    var pts = this.getPoints(divisions);

    var segment, pathGeometry = new THREE.Object3D;
    if(!lineMaterial) lineMaterial = new THREE.LineBasicMaterial( { color:0x000000, opacity:0.7 } );

    for(var i=1; i<pts.length; i++) {
        var pathSegment = new THREE.Geometry();
        pathSegment.vertices.push( new THREE.Vertex( new THREE.Vector3( pts[i-1].x, pts[i-1].y, 0 ) ) );
        pathSegment.vertices.push( new THREE.Vertex( new THREE.Vector3( pts[i].x, pts[i].y, 0) ) );
        segment = new THREE.Line( pathSegment , lineMaterial );
        pathGeometry.addChild(segment);
    }

    return(pathGeometry);
};

In the .html file that contains the scene, etc.:

var glyphArray=[];
glyphArray.push( new THREE.Vector2 (610, 320) );
glyphArray.push( new THREE.Vector2 (450, 300) );
glyphArray.push( new THREE.Vector2 (392, 392) );
glyphArray.push( new THREE.Vector2 (266, 438) );
glyphArray.push( new THREE.Vector2 (190, 570) );
glyphArray.push( new THREE.Vector2 (190, 600) );
glyphArray.push( new THREE.Vector2 (160, 620) );
glyphArray.push( new THREE.Vector2 (160, 650) );
glyphArray.push( new THREE.Vector2 (180, 640) );
glyphArray.push( new THREE.Vector2 (165, 680) );
glyphArray.push( new THREE.Vector2 (150, 670) );
glyphArray.push( new THREE.Vector2 (90, 737) );
glyphArray.push( new THREE.Vector2 (80, 795) );
glyphArray.push( new THREE.Vector2 (50, 835) );
glyphArray.push( new THREE.Vector2 (64, 870) );
glyphArray.push( new THREE.Vector2 (60, 945) );
glyphArray.push( new THREE.Vector2 (300, 945) );
glyphArray.push( new THREE.Vector2 (300, 743) );
glyphArray.push( new THREE.Vector2 (600, 473) );
glyphArray.push( new THREE.Vector2 (626, 425) );
glyphArray.push( new THREE.Vector2 (600, 370) );
glyphArray.push( new THREE.Vector2 (610, 320) );

var myPath = new THREE.Path();
myPath.fromPoints(glyphArray);
myPathGeometry = myPath.createPathGeometry(4, null);
scene.addObject(myPathGeometry);

Note: One of the problems that might have to be rectified is the fact that getPoints(divisions) returns an array of THREE.Vector2's, which I then transform into THREE.Vertex(new THREE.Vector3)'s so that they represent locations in 3D-space. I'm not sure if getPoints should be changed to return an array of THREE.Vector3s or THREE.Vertex(new THREE.Vector3)'s, or if there should be two separate functions, get2DPoints and get3DPoints, or if there should be some sort of toggle parameter that is used in an if statement in order to return the appropriate type of vertex, e.g.:

if(paramReturn3D) { 
    pts.push( new THREE.Vector3( args[0], args[1], 0 ) ); 
} else {
    pts.push( new THREE.Vector2( args[0], args[1] ) ); 
}
zz85 commented 12 years ago

@SolarCoordinates Much of the code needed has been written in TextGeometry, but what we are trying to do is to refactor it to a usable and useful API. Hope you're having fun with three.js though.. ;)

If it is a 2d path, it should get 2d vectors. If its a 3d path, it make sense to return 3d vectors. However, what we need right now is just 2d path, because I think it would be ExtrudeGeometry's job to turn it into a 3D vectors.

zz85 commented 12 years ago

If you find it useful, I've decided to post a little of how TextGeometry works on my blog. http://www.lab4games.net/zz85/blog/2011/07/11/threejs-3d-text/

zz85 commented 12 years ago

@SolarCoordinates thanks for the example. i've updated my api to support the "california" extrusion for now.

https://gist.github.com/1074794

@mrdoob, right now can support a list of closed points and extrude it. I think this fits the ExtrudeGeometry you were thinking at the start.

var shape = new THREE.Shape(vectorArray);
var extruded = new THREE.ExtrudeGeometry( shape, {
    amount: 20
});

However Shape and ExtrudeGeometry still needs more work to support holes and multiple shapes.

SolarCoordinates commented 12 years ago

I was going to try to save you guys the trouble, but it seems you are making progress and doing it differently than what I had planned (instead of redirecting everything to the existing font extrusion code [e.g. THREE.Shape.prototype.triangulate = function() { return THREE.FontUtils.Triangulate( this.getPoints(), true ); }; ], I was going to make the glyph-processing function and the parth -> triangulated mesh conversion a subset of THREE.Shape [e.g. THREE.Shape.fromText(...) and THREE.Shape.to2DMesh(...), and suggest that the existing font extrusion be gotten rid of completely, as it would then be handled by THREE.Shape.fromText(...), THREE.Shape.to2DMesh(...), and THREE.ExtrudeGeometry(...)) , so I'll let you handle it and try to learn from your code, as you are no doubt much better than I. :)

It's been ~6 years since I've programmed anything, and I've never done any serious javascript, so you guys probably wouldn't approve of my code anyways. :)

zz85 commented 12 years ago

@SolarCoordinates Thanks for your attempt.. Not that I do not approve your code, and I think you've spent some amount of time getting this to work, but I wouldn't want to rush coding this quickly for a few reasons - I think of writing a better API requires some careful thinking, and that I can prevent directly copying some of my bad code in TextGeometry (already I found some designs flaws I previously overlooked).

There's some slides of "How to Design a Good API and Why it Matter" which there pretty good points we can learn from http://aarontgrogg.com/wp-content/uploads/2009/09/How-to-Build-API-and-why-it-matters.pdf

zz85 commented 12 years ago

@alteredq @mrdoob I've just pushed an example called canvas_geometry_shape.html using the new shape, path and extrudeGeometry API. this allows 3d shapes to be created with path api using moveTo, bezierCurveTo, quadraticCurveTo to define shapes. :)

alteredq commented 12 years ago

@zz85 Awesome, merged ;)

zz85 commented 12 years ago

@alteredq quick update to add spline support for shapes (should probably refactor to use three.spline), stepped extrusions, and extrusion via paths. this is bad, spending too much time down the rabbit hole >.< also updated example

@mrdoob is this what you were thinking of for ExtrudeGeometry?

alteredq commented 12 years ago

@zz85 Looking good, merged ;)

zz85 commented 12 years ago

was just looking at @SolarCoordinates createPathGeometry code again and wonder if we should include it in THREE.Path?

could be useful for debuging/displaying a path in 3d space.

also, while right now shapes and path are currently in 2d space (which is simpler for now), in future we could extend it for 3d path and 3d shapes, although that might be a little more complex to use

mrdoob commented 12 years ago

@zz85: Awesome implementation!

@SolarCoordinates: Good work too! :)

was just looking at @SolarCoordinates createPathGedometry code again and wonder if we should include it in THREE.Path?

You mean using ExtrudeGeometry internally?

alteredq commented 12 years ago

was just looking at @SolarCoordinates createPathGeometry code again and wonder if we should include it in THREE.Path?

Having 3d line objects created from paths / shapes could be useful.

Though createPathGeometry code is not efficient - it should be a single Line object for the whole path - single Geometry with many vertices to create a single Line ( LineStrip type for a continuous line or LinePieces type for line composed of individual segments if there are discontinuities).

There is something like this in PathCamera, used for debug display of spline:

https://github.com/mrdoob/three.js/blob/master/src/extras/cameras/PathCamera.js#L251

Also there are particles for interpolated vertices and spheres for waypoints:

https://github.com/mrdoob/three.js/blob/master/src/extras/cameras/PathCamera.js#L269

also, while right now shapes and path are currently in 2d space (which is simpler for now), in future we could extend it for 3d path and 3d shapes, although that might be a little more complex to use

Yes, 3d paths could eventually be a nice extension. Currently there is just 3d Catmull-Rom Spline which is used mainly to drive PathCamera.

And yes, this may be hard to use, especially for 3d shapes. 3d paths probably would be most useful for driving animations of objects or cameras.

zz85 commented 12 years ago

path geometry is just to display the 2d path in the 3d scene. @alteredq thanks for the reference, i'll look into that over this weekend maybe :) also i'm thinking if i should refactor to have use different objects for the different curves eg. Path is an array of curves, which could be straight lines, quadratic bezier, cubic, catmull rom splines etc...

One benefit might be having common methods on curves like but it might create more classes too curve.getPoints(); curve.getPoint(t); curve.getPointAtArclength(t); curve.transform(params);

mrdoob commented 12 years ago

curve.getPointAtArclength(t);

+1! ^^

zz85 commented 12 years ago

I've now added Curved Bevels (Mis-spelled it as Bezel in TextGeometry;) as well as holes support in Extrude Geometry.

See (http://i52.tinypic.com/345im0x.png). I think bevels should work better than before, except that it doesn't seem to play well with ExtrudeWithPath.

My triangulation wrapper is also giving me a headaches because there are cases when holes removal is not successful. (this usually happens when shape points are few and 2 triangles cut to a hole actually cuts into another hole). I've came out with a new method to recursively break shapes apart until there are no holes, but there might still be a chance of untriangulated scenarios and I haven't gotten to implementing that.

I've also added a wrapper to use poly2tri - a 2d constrained Delaunay triangulation (CDT) method. It seems to work pretty well for the cases I tested, but it might mean we need to import some more dependancies (poly2tri.js and namespace.js) (one day we should implement Delaunay triangulation, i think it could get good usage in three.js :)

ExtrudeGeometry should be usual now and I think I would want to take a short break on the triangulation part for now. Next steps would be to support multiple shapes, and updating Text to use Shape internally.

Feedback/Comments?

Also updated the example (https://github.com/zz85/three.js/blob/e37a02805ab44552d8e07dcf28d7c43b5028f4e9/examples/canvas_geometry_shape.html)

alteredq commented 12 years ago

@zz85 Nice work, merged ;).

See (http://i52.tinypic.com/345im0x.png). I think bevels should work better than before, except that it doesn't seem to play well with ExtrudeWithPath.

Looks great ;)

Just with more triangles it starts to be a bit too much for CanvasRenderer, maybe we should switch this example to WebGLRenderer.

I've also added a wrapper to use poly2tri - a 2d constrained Delaunay triangulation (CDT) method. It seems to work pretty well for the cases I tested, but it might mean we need to import some more dependancies (poly2tri.js and namespace.js) (one day we should implement Delaunay triangulation, i think it could get good usage in three.js :)

Hmmm, poly2tri looks interesting, though not sure about introducing dependencies (for the moment there are none).

Delaunay triangulation is indeed something useful, it tends to pop up in many places.

mrdoob commented 12 years ago

Agreed agreed!

zz85 commented 12 years ago

was travelling to and fro KL over the weekends so I had some thing to work and think about implementing Paths/Shapes for Text. Question: do we still wish to maintain the old TextGeometry api?

    var text3d = new TextGeometry(text, options);

Or do it FactoryStyle

    var text3d = FontUtils.createText(text, options);

In a more complete but tedious manner,

    var textPath = new TextPath(text);
    var textShapes = textPath.toShapes();
    var text3d = new ExtrudeGeometry(textShapes, options);

Or Factory + Extrude

    var textShapes = FontUtils.getTextShapes(text, fontOptions);
    text3d = new ExtrudeGeometry(textShapes, extrudeOptions);

I think I might prefer a simple style (1st or 2nd) but I might want the last method because I could modify the shape (like wrapping round a bezier) before extruding.

It seems my currently implementation is a little memory hungry so there's still so work to be done there. Also realized that my bevel don't work nice on concave shapes, which means some work to be done there again :(