diff --git a/src/extras/core/CurvePath.js b/src/extras/core/CurvePath.js index 380f83dc241c245e5d724b5d4aab7c8146211dbd..9cac62f9f028bb5192544bba88415b963ded9570 100644 --- a/src/extras/core/CurvePath.js +++ b/src/extras/core/CurvePath.js @@ -16,161 +16,149 @@ THREE.CurvePath = function () { }; -THREE.CurvePath.prototype = Object.create( THREE.Curve.prototype ); -THREE.CurvePath.prototype.constructor = THREE.CurvePath; +THREE.CurvePath.prototype = Object.assign( Object.create( THREE.Curve.prototype ), { -THREE.CurvePath.prototype.add = function ( curve ) { + constructor: THREE.CurvePath, - this.curves.push( curve ); + add: function ( curve ) { -}; - -/* -THREE.CurvePath.prototype.checkConnection = function() { - // TODO - // If the ending of curve is not connected to the starting - // or the next curve, then, this is not a real path -}; -*/ + this.curves.push( curve ); -THREE.CurvePath.prototype.closePath = function() { + }, - // TODO Test - // and verify for vector3 (needs to implement equals) - // Add a line curve if start and end of lines are not connected - var startPoint = this.curves[ 0 ].getPoint( 0 ); - var endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 ); + closePath: function () { - if ( ! startPoint.equals( endPoint ) ) { + // TODO Test + // and verify for vector3 (needs to implement equals) + // Add a line curve if start and end of lines are not connected + var startPoint = this.curves[ 0 ].getPoint( 0 ); + var endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 ); - this.curves.push( new THREE.LineCurve( endPoint, startPoint ) ); + if ( ! startPoint.equals( endPoint ) ) { - } + this.curves.push( new THREE.LineCurve( endPoint, startPoint ) ); -}; + } -// To get accurate point with reference to -// entire path distance at time t, -// following has to be done: + }, -// 1. Length of each sub path have to be known -// 2. Locate and identify type of curve -// 3. Get t for the curve -// 4. Return curve.getPointAt(t') + // To get accurate point with reference to + // entire path distance at time t, + // following has to be done: -THREE.CurvePath.prototype.getPoint = function( t ) { + // 1. Length of each sub path have to be known + // 2. Locate and identify type of curve + // 3. Get t for the curve + // 4. Return curve.getPointAt(t') - var d = t * this.getLength(); - var curveLengths = this.getCurveLengths(); - var i = 0; + getPoint: function ( t ) { - // To think about boundaries points. + var d = t * this.getLength(); + var curveLengths = this.getCurveLengths(); + var i = 0; - while ( i < curveLengths.length ) { + // To think about boundaries points. - if ( curveLengths[ i ] >= d ) { + while ( i < curveLengths.length ) { - var diff = curveLengths[ i ] - d; - var curve = this.curves[ i ]; + if ( curveLengths[ i ] >= d ) { - var u = 1 - diff / curve.getLength(); + var diff = curveLengths[ i ] - d; + var curve = this.curves[ i ]; - return curve.getPointAt( u ); + var u = 1 - diff / curve.getLength(); - } + return curve.getPointAt( u ); - i ++; + } - } + i ++; - return null; + } - // loop where sum != 0, sum > d , sum+1 d , sum+1 0 ) { - cpx = args[ 2 ]; - cpy = args[ 3 ]; + laste = points[ points.length - 1 ]; - cpx1 = args[ 0 ]; - cpy1 = args[ 1 ]; + cpx0 = laste.x; + cpy0 = laste.y; - if ( points.length > 0 ) { + } else { - laste = points[ points.length - 1 ]; + laste = this.actions[ i - 1 ].args; - cpx0 = laste.x; - cpy0 = laste.y; + cpx0 = laste[ laste.length - 2 ]; + cpy0 = laste[ laste.length - 1 ]; - } else { + } - laste = this.actions[ i - 1 ].args; + for ( var j = 1; j <= divisions; j ++ ) { - cpx0 = laste[ laste.length - 2 ]; - cpy0 = laste[ laste.length - 1 ]; + var t = j / divisions; - } + tx = b2( t, cpx0, cpx1, cpx ); + ty = b2( t, cpy0, cpy1, cpy ); - for ( var j = 1; j <= divisions; j ++ ) { + points.push( new THREE.Vector2( tx, ty ) ); - var t = j / divisions; + } - tx = b2( t, cpx0, cpx1, cpx ); - ty = b2( t, cpy0, cpy1, cpy ); + break; - points.push( new THREE.Vector2( tx, ty ) ); + case 'bezierCurveTo': - } + cpx = args[ 4 ]; + cpy = args[ 5 ]; - break; + cpx1 = args[ 0 ]; + cpy1 = args[ 1 ]; - case 'bezierCurveTo': + cpx2 = args[ 2 ]; + cpy2 = args[ 3 ]; - cpx = args[ 4 ]; - cpy = args[ 5 ]; + if ( points.length > 0 ) { - cpx1 = args[ 0 ]; - cpy1 = args[ 1 ]; + laste = points[ points.length - 1 ]; - cpx2 = args[ 2 ]; - cpy2 = args[ 3 ]; + cpx0 = laste.x; + cpy0 = laste.y; - if ( points.length > 0 ) { + } else { - laste = points[ points.length - 1 ]; + laste = this.actions[ i - 1 ].args; - cpx0 = laste.x; - cpy0 = laste.y; + cpx0 = laste[ laste.length - 2 ]; + cpy0 = laste[ laste.length - 1 ]; - } else { + } - laste = this.actions[ i - 1 ].args; - cpx0 = laste[ laste.length - 2 ]; - cpy0 = laste[ laste.length - 1 ]; + for ( var j = 1; j <= divisions; j ++ ) { - } + var t = j / divisions; + tx = b3( t, cpx0, cpx1, cpx2, cpx ); + ty = b3( t, cpy0, cpy1, cpy2, cpy ); - for ( var j = 1; j <= divisions; j ++ ) { + points.push( new THREE.Vector2( tx, ty ) ); - var t = j / divisions; + } - tx = b3( t, cpx0, cpx1, cpx2, cpx ); - ty = b3( t, cpy0, cpy1, cpy2, cpy ); + break; - points.push( new THREE.Vector2( tx, ty ) ); + case 'splineThru': - } + laste = this.actions[ i - 1 ].args; - break; + var last = new THREE.Vector2( laste[ laste.length - 2 ], laste[ laste.length - 1 ] ); + var spts = [ last ]; - case 'splineThru': + var n = divisions * args[ 0 ].length; - laste = this.actions[ i - 1 ].args; + spts = spts.concat( args[ 0 ] ); - var last = new THREE.Vector2( laste[ laste.length - 2 ], laste[ laste.length - 1 ] ); - var spts = [ last ]; + var spline = new THREE.SplineCurve( spts ); - var n = divisions * args[ 0 ].length; + for ( var j = 1; j <= n; j ++ ) { - spts = spts.concat( args[ 0 ] ); + points.push( spline.getPointAt( j / n ) ); - var spline = new THREE.SplineCurve( spts ); + } - for ( var j = 1; j <= n; j ++ ) { + break; - points.push( spline.getPointAt( j / n ) ); + case 'arc': - } + var aX = args[ 0 ], aY = args[ 1 ], + aRadius = args[ 2 ], + aStartAngle = args[ 3 ], aEndAngle = args[ 4 ], + aClockwise = !! args[ 5 ]; - break; + var deltaAngle = aEndAngle - aStartAngle; + var angle; + var tdivisions = divisions * 2; - case 'arc': + for ( var j = 1; j <= tdivisions; j ++ ) { - var aX = args[ 0 ], aY = args[ 1 ], - aRadius = args[ 2 ], - aStartAngle = args[ 3 ], aEndAngle = args[ 4 ], - aClockwise = !! args[ 5 ]; + var t = j / tdivisions; - var deltaAngle = aEndAngle - aStartAngle; - var angle; - var tdivisions = divisions * 2; + if ( ! aClockwise ) { - for ( var j = 1; j <= tdivisions; j ++ ) { + t = 1 - t; - var t = j / tdivisions; + } - if ( ! aClockwise ) { + angle = aStartAngle + t * deltaAngle; - t = 1 - t; + tx = aX + aRadius * Math.cos( angle ); + ty = aY + aRadius * Math.sin( angle ); - } + //console.log('t', t, 'angle', angle, 'tx', tx, 'ty', ty); - angle = aStartAngle + t * deltaAngle; + points.push( new THREE.Vector2( tx, ty ) ); - tx = aX + aRadius * Math.cos( angle ); - ty = aY + aRadius * Math.sin( angle ); + } - //console.log('t', t, 'angle', angle, 'tx', tx, 'ty', ty); + //console.log(points); - points.push( new THREE.Vector2( tx, ty ) ); + break; - } + case 'ellipse': - //console.log(points); + var aX = args[ 0 ], aY = args[ 1 ], + xRadius = args[ 2 ], + yRadius = args[ 3 ], + aStartAngle = args[ 4 ], aEndAngle = args[ 5 ], + aClockwise = !! args[ 6 ], + aRotation = args[ 7 ]; - break; - case 'ellipse': + var deltaAngle = aEndAngle - aStartAngle; + var angle; + var tdivisions = divisions * 2; - var aX = args[ 0 ], aY = args[ 1 ], - xRadius = args[ 2 ], - yRadius = args[ 3 ], - aStartAngle = args[ 4 ], aEndAngle = args[ 5 ], - aClockwise = !! args[ 6 ], - aRotation = args[ 7 ]; + var cos, sin; + if ( aRotation !== 0 ) { + cos = Math.cos( aRotation ); + sin = Math.sin( aRotation ); - var deltaAngle = aEndAngle - aStartAngle; - var angle; - var tdivisions = divisions * 2; + } - var cos, sin; - if ( aRotation !== 0 ) { + for ( var j = 1; j <= tdivisions; j ++ ) { - cos = Math.cos( aRotation ); - sin = Math.sin( aRotation ); + var t = j / tdivisions; - } + if ( ! aClockwise ) { - for ( var j = 1; j <= tdivisions; j ++ ) { + t = 1 - t; - var t = j / tdivisions; + } - if ( ! aClockwise ) { + angle = aStartAngle + t * deltaAngle; - t = 1 - t; + tx = aX + xRadius * Math.cos( angle ); + ty = aY + yRadius * Math.sin( angle ); - } + if ( aRotation !== 0 ) { - angle = aStartAngle + t * deltaAngle; + var x = tx, y = ty; - tx = aX + xRadius * Math.cos( angle ); - ty = aY + yRadius * Math.sin( angle ); + // Rotate the point about the center of the ellipse. + tx = ( x - aX ) * cos - ( y - aY ) * sin + aX; + ty = ( x - aX ) * sin + ( y - aY ) * cos + aY; - if ( aRotation !== 0 ) { + } - var x = tx, y = ty; + //console.log('t', t, 'angle', angle, 'tx', tx, 'ty', ty); - // Rotate the point about the center of the ellipse. - tx = ( x - aX ) * cos - ( y - aY ) * sin + aX; - ty = ( x - aX ) * sin + ( y - aY ) * cos + aY; + points.push( new THREE.Vector2( tx, ty ) ); } - //console.log('t', t, 'angle', angle, 'tx', tx, 'ty', ty); - - points.push( new THREE.Vector2( tx, ty ) ); + //console.log(points); - } - - //console.log(points); - - break; + break; - } // end switch + } // end switch - } + } - // Normalize to remove the closing point by default. - var lastPoint = points[ points.length - 1 ]; - if ( Math.abs( lastPoint.x - points[ 0 ].x ) < Number.EPSILON && - Math.abs( lastPoint.y - points[ 0 ].y ) < Number.EPSILON ) - points.splice( points.length - 1, 1 ); + // Normalize to remove the closing point by default. + var lastPoint = points[ points.length - 1 ]; + if ( Math.abs( lastPoint.x - points[ 0 ].x ) < Number.EPSILON && + Math.abs( lastPoint.y - points[ 0 ].y ) < Number.EPSILON ) + points.splice( points.length - 1, 1 ); - if ( this.autoClose ) { + if ( this.autoClose ) { - points.push( points[ 0 ] ); + points.push( points[ 0 ] ); - } + } - return points; + return points; -}; + }, -// -// Breaks path into shapes -// -// Assumptions (if parameter isCCW==true the opposite holds): -// - solid shapes are defined clockwise (CW) -// - holes are defined counterclockwise (CCW) -// -// If parameter noHoles==true: -// - all subPaths are regarded as solid shapes -// - definition order CW/CCW has no relevance -// + toShapes: function ( isCCW, noHoles ) { -THREE.Path.prototype.toShapes = function( isCCW, noHoles ) { + function extractSubpaths( inActions ) { - function extractSubpaths( inActions ) { + var subPaths = [], lastPath = new THREE.Path(); - var subPaths = [], lastPath = new THREE.Path(); + for ( var i = 0, l = inActions.length; i < l; i ++ ) { - for ( var i = 0, l = inActions.length; i < l; i ++ ) { + var item = inActions[ i ]; - var item = inActions[ i ]; + var args = item.args; + var action = item.action; - var args = item.args; - var action = item.action; + if ( action === 'moveTo' ) { - if ( action === 'moveTo' ) { + if ( lastPath.actions.length !== 0 ) { - if ( lastPath.actions.length !== 0 ) { + subPaths.push( lastPath ); + lastPath = new THREE.Path(); - subPaths.push( lastPath ); - lastPath = new THREE.Path(); + } } + lastPath[ action ].apply( lastPath, args ); + } - lastPath[ action ].apply( lastPath, args ); + if ( lastPath.actions.length !== 0 ) { - } + subPaths.push( lastPath ); - if ( lastPath.actions.length !== 0 ) { + } + + // console.log(subPaths); - subPaths.push( lastPath ); + return subPaths; } - // console.log(subPaths); + function toShapesNoHoles( inSubpaths ) { - return subPaths; + var shapes = []; - } + for ( var i = 0, l = inSubpaths.length; i < l; i ++ ) { - function toShapesNoHoles( inSubpaths ) { + var tmpPath = inSubpaths[ i ]; - var shapes = []; + var tmpShape = new THREE.Shape(); + tmpShape.actions = tmpPath.actions; + tmpShape.curves = tmpPath.curves; - for ( var i = 0, l = inSubpaths.length; i < l; i ++ ) { + shapes.push( tmpShape ); - var tmpPath = inSubpaths[ i ]; + } - var tmpShape = new THREE.Shape(); - tmpShape.actions = tmpPath.actions; - tmpShape.curves = tmpPath.curves; + //console.log("shape", shapes); - shapes.push( tmpShape ); + return shapes; } - //console.log("shape", shapes); + function isPointInsidePolygon( inPt, inPolygon ) { - return shapes; + var polyLen = inPolygon.length; - } + // inPt on polygon contour => immediate success or + // toggling of inside/outside at every single! intersection point of an edge + // with the horizontal line through inPt, left of inPt + // not counting lowerY endpoints of edges and whole edges on that line + var inside = false; + for ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) { - function isPointInsidePolygon( inPt, inPolygon ) { + var edgeLowPt = inPolygon[ p ]; + var edgeHighPt = inPolygon[ q ]; - var polyLen = inPolygon.length; + var edgeDx = edgeHighPt.x - edgeLowPt.x; + var edgeDy = edgeHighPt.y - edgeLowPt.y; - // inPt on polygon contour => immediate success or - // toggling of inside/outside at every single! intersection point of an edge - // with the horizontal line through inPt, left of inPt - // not counting lowerY endpoints of edges and whole edges on that line - var inside = false; - for ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) { + if ( Math.abs( edgeDy ) > Number.EPSILON ) { - var edgeLowPt = inPolygon[ p ]; - var edgeHighPt = inPolygon[ q ]; + // not parallel + if ( edgeDy < 0 ) { - var edgeDx = edgeHighPt.x - edgeLowPt.x; - var edgeDy = edgeHighPt.y - edgeLowPt.y; + edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx; + edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy; - if ( Math.abs( edgeDy ) > Number.EPSILON ) { + } + if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue; - // not parallel - if ( edgeDy < 0 ) { + if ( inPt.y === edgeLowPt.y ) { - edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx; - edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy; + if ( inPt.x === edgeLowPt.x ) return true; // inPt is on contour ? + // continue; // no intersection or edgeLowPt => doesn't count !!! - } - if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue; + } else { - if ( inPt.y === edgeLowPt.y ) { + var perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y ); + if ( perpEdge === 0 ) return true; // inPt is on contour ? + if ( perpEdge < 0 ) continue; + inside = ! inside; // true intersection left of inPt - if ( inPt.x === edgeLowPt.x ) return true; // inPt is on contour ? - // continue; // no intersection or edgeLowPt => doesn't count !!! + } } else { - var perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y ); - if ( perpEdge === 0 ) return true; // inPt is on contour ? - if ( perpEdge < 0 ) continue; - inside = ! inside; // true intersection left of inPt + // parallel or collinear + if ( inPt.y !== edgeLowPt.y ) continue; // parallel + // edge lies on the same horizontal line as inPt + if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) || + ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true; // inPt: Point on contour ! + // continue; } - } else { - - // parallel or collinear - if ( inPt.y !== edgeLowPt.y ) continue; // parallel - // edge lies on the same horizontal line as inPt - if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) || - ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true; // inPt: Point on contour ! - // continue; - } + return inside; + } - return inside; + var isClockWise = THREE.ShapeUtils.isClockWise; - } + var subPaths = extractSubpaths( this.actions ); + if ( subPaths.length === 0 ) return []; - var isClockWise = THREE.ShapeUtils.isClockWise; + if ( noHoles === true ) return toShapesNoHoles( subPaths ); - var subPaths = extractSubpaths( this.actions ); - if ( subPaths.length === 0 ) return []; - if ( noHoles === true ) return toShapesNoHoles( subPaths ); + var solid, tmpPath, tmpShape, shapes = []; + if ( subPaths.length === 1 ) { - var solid, tmpPath, tmpShape, shapes = []; - - if ( subPaths.length === 1 ) { + tmpPath = subPaths[ 0 ]; + tmpShape = new THREE.Shape(); + tmpShape.actions = tmpPath.actions; + tmpShape.curves = tmpPath.curves; + shapes.push( tmpShape ); + return shapes; - tmpPath = subPaths[ 0 ]; - tmpShape = new THREE.Shape(); - tmpShape.actions = tmpPath.actions; - tmpShape.curves = tmpPath.curves; - shapes.push( tmpShape ); - return shapes; + } - } + var holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() ); + holesFirst = isCCW ? ! holesFirst : holesFirst; - var holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() ); - holesFirst = isCCW ? ! holesFirst : holesFirst; + // console.log("Holes first", holesFirst); - // console.log("Holes first", holesFirst); + var betterShapeHoles = []; + var newShapes = []; + var newShapeHoles = []; + var mainIdx = 0; + var tmpPoints; - var betterShapeHoles = []; - var newShapes = []; - var newShapeHoles = []; - var mainIdx = 0; - var tmpPoints; + newShapes[ mainIdx ] = undefined; + newShapeHoles[ mainIdx ] = []; - newShapes[ mainIdx ] = undefined; - newShapeHoles[ mainIdx ] = []; + for ( var i = 0, l = subPaths.length; i < l; i ++ ) { - for ( var i = 0, l = subPaths.length; i < l; i ++ ) { + tmpPath = subPaths[ i ]; + tmpPoints = tmpPath.getPoints(); + solid = isClockWise( tmpPoints ); + solid = isCCW ? ! solid : solid; - tmpPath = subPaths[ i ]; - tmpPoints = tmpPath.getPoints(); - solid = isClockWise( tmpPoints ); - solid = isCCW ? ! solid : solid; + if ( solid ) { - if ( solid ) { + if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++; - if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++; + newShapes[ mainIdx ] = { s: new THREE.Shape(), p: tmpPoints }; + newShapes[ mainIdx ].s.actions = tmpPath.actions; + newShapes[ mainIdx ].s.curves = tmpPath.curves; - newShapes[ mainIdx ] = { s: new THREE.Shape(), p: tmpPoints }; - newShapes[ mainIdx ].s.actions = tmpPath.actions; - newShapes[ mainIdx ].s.curves = tmpPath.curves; + if ( holesFirst ) mainIdx ++; + newShapeHoles[ mainIdx ] = []; - if ( holesFirst ) mainIdx ++; - newShapeHoles[ mainIdx ] = []; + //console.log('cw', i); - //console.log('cw', i); + } else { - } else { + newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } ); - newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } ); + //console.log('ccw', i); - //console.log('ccw', i); + } } - } + // only Holes? -> probably all Shapes with wrong orientation + if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths ); - // only Holes? -> probably all Shapes with wrong orientation - if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths ); + if ( newShapes.length > 1 ) { - if ( newShapes.length > 1 ) { + var ambiguous = false; + var toChange = []; - var ambiguous = false; - var toChange = []; + for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { - for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { + betterShapeHoles[ sIdx ] = []; - betterShapeHoles[ sIdx ] = []; + } - } + for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { - for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { + var sho = newShapeHoles[ sIdx ]; - var sho = newShapeHoles[ sIdx ]; + for ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) { - for ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) { + var ho = sho[ hIdx ]; + var hole_unassigned = true; - var ho = sho[ hIdx ]; - var hole_unassigned = true; + for ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) { - for ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) { + if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) { - if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) { + if ( sIdx !== s2Idx ) toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } ); + if ( hole_unassigned ) { - if ( sIdx !== s2Idx ) toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } ); - if ( hole_unassigned ) { + hole_unassigned = false; + betterShapeHoles[ s2Idx ].push( ho ); - hole_unassigned = false; - betterShapeHoles[ s2Idx ].push( ho ); + } else { - } else { + ambiguous = true; - ambiguous = true; + } } } + if ( hole_unassigned ) { - } - if ( hole_unassigned ) { + betterShapeHoles[ sIdx ].push( ho ); - betterShapeHoles[ sIdx ].push( ho ); + } } } + // console.log("ambiguous: ", ambiguous); + if ( toChange.length > 0 ) { - } - // console.log("ambiguous: ", ambiguous); - if ( toChange.length > 0 ) { + // console.log("to change: ", toChange); + if ( ! ambiguous ) newShapeHoles = betterShapeHoles; - // console.log("to change: ", toChange); - if ( ! ambiguous ) newShapeHoles = betterShapeHoles; + } } - } + var tmpHoles; - var tmpHoles; + for ( var i = 0, il = newShapes.length; i < il; i ++ ) { - for ( var i = 0, il = newShapes.length; i < il; i ++ ) { + tmpShape = newShapes[ i ].s; + shapes.push( tmpShape ); + tmpHoles = newShapeHoles[ i ]; - tmpShape = newShapes[ i ].s; - shapes.push( tmpShape ); - tmpHoles = newShapeHoles[ i ]; + for ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) { - for ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) { + tmpShape.holes.push( tmpHoles[ j ].h ); - tmpShape.holes.push( tmpHoles[ j ].h ); + } } - } + //console.log("shape", shapes); - //console.log("shape", shapes); + return shapes; - return shapes; + } -}; +} ); diff --git a/src/extras/core/Shape.js b/src/extras/core/Shape.js index e9c73f1d78e60083eeda6d7bb4a6eb41b11c542b..b785e068be7b86d3562dc591e88fa78747b73128 100644 --- a/src/extras/core/Shape.js +++ b/src/extras/core/Shape.js @@ -17,57 +17,57 @@ THREE.Shape = function () { }; -THREE.Shape.prototype = Object.create( THREE.Path.prototype ); -THREE.Shape.prototype.constructor = THREE.Shape; +THREE.Shape.prototype = Object.assign( Object.create( THREE.Path.prototype ), { -// Convenience method to return ExtrudeGeometry + constructor: THREE.Shape, -THREE.Shape.prototype.extrude = function ( options ) { + // Convenience method to return ExtrudeGeometry - return new THREE.ExtrudeGeometry( this, options ); + extrude: function ( options ) { -}; + return new THREE.ExtrudeGeometry( this, options ); -// Convenience method to return ShapeGeometry + }, -THREE.Shape.prototype.makeGeometry = function ( options ) { + // Convenience method to return ShapeGeometry - return new THREE.ShapeGeometry( this, options ); + makeGeometry: function ( options ) { -}; + return new THREE.ShapeGeometry( this, options ); -// Get points of holes + }, -THREE.Shape.prototype.getPointsHoles = function ( divisions ) { + getPointsHoles: function ( divisions ) { - var holesPts = []; + var holesPts = []; - for ( var i = 0, l = this.holes.length; i < l; i ++ ) { + for ( var i = 0, l = this.holes.length; i < l; i ++ ) { - holesPts[ i ] = this.holes[ i ].getPoints( divisions ); + holesPts[ i ] = this.holes[ i ].getPoints( divisions ); - } + } - return holesPts; + return holesPts; -}; + }, + // Get points of shape and holes (keypoints based on segments parameter) -// Get points of shape and holes (keypoints based on segments parameter) + extractAllPoints: function ( divisions ) { -THREE.Shape.prototype.extractAllPoints = function ( divisions ) { + return { - return { + shape: this.getPoints( divisions ), + holes: this.getPointsHoles( divisions ) - shape: this.getPoints( divisions ), - holes: this.getPointsHoles( divisions ) + }; - }; + }, -}; + extractPoints: function ( divisions ) { -THREE.Shape.prototype.extractPoints = function ( divisions ) { + return this.extractAllPoints( divisions ); - return this.extractAllPoints( divisions ); + } -}; +} );