diff --git a/.gitmodules b/.gitmodules index bce8bb6f..1c7b78a3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -695,3 +695,6 @@ [submodule "vendor/grammars/language-click"] path = vendor/grammars/language-click url = https://github.com/stenverbois/language-click.git +[submodule "vendor/grammars/language-maxscript"] + path = vendor/grammars/language-maxscript + url = https://github.com/Alhadis/language-maxscript diff --git a/grammars.yml b/grammars.yml index 6b28c97d..b3278e14 100644 --- a/grammars.yml +++ b/grammars.yml @@ -349,6 +349,8 @@ vendor/grammars/language-javascript: vendor/grammars/language-jsoniq/: - source.jq - source.xq +vendor/grammars/language-maxscript: +- source.maxscript vendor/grammars/language-ncl: - source.ncl vendor/grammars/language-python: diff --git a/lib/linguist/heuristics.rb b/lib/linguist/heuristics.rb index 0a1ab912..7c1c7db1 100644 --- a/lib/linguist/heuristics.rb +++ b/lib/linguist/heuristics.rb @@ -238,8 +238,10 @@ module Linguist disambiguate ".ms" do |data| if /^[.'][a-z][a-z](\s|$)/i.match(data) Language["Groff"] - elsif /((^|\s)move?[. ])|\.(include|globa?l)\s/.match(data) + elsif /(?" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import scipy.ndimage\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy\n", + "\n", + "\n", + "def plotImage(image, cmap='gray'):\n", + " birdsPlot = plt.imshow(image, cmap=cmap)\n", + " birdsPlot.axes.get_xaxis().set_visible(False)\n", + " birdsPlot.axes.get_yaxis().set_visible(False)\n", + " plt.show()\n", + "\n", + "birdsOriginal = scipy.ndimage.imread(\"images/birds.jpg\")\n", + "\n", + "print(\"Original image:\")\n", + "plotImage(birdsOriginal)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Binary image:\n" + ] + }, + { + "data": { + "image/png": "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\nkXQBQKP/AwtvTcpUtjvBAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "birdsColorMap = birdsOriginal < [100,100,100]\n", + "\n", + "r,g,b = birdsColorMap.T\n", + "\n", + "# Hack: Using the green channel, because in this particular image, when inverted, \n", + "# pixels with full green would mean it's a white pixel.\n", + "\n", + "binaryBirds = g.T\n", + "print(\"Binary image:\")\n", + "plotImage(binaryBirds)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# I've chosen a disk-type structuring element so as to avoid birds' wings reaching out and touching others on dilation\n", + "struct = [[0, 0, 1, 1, 1, 0, 0],\n", + " [0, 1, 1, 1, 1, 1, 0],\n", + " [1, 1, 1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1, 1, 1],\n", + " [0, 1, 1, 1, 1, 1, 0],\n", + " [0, 0, 1, 1, 1, 0, 0]]\n", + "\n", + "\n", + "birdsImage = binaryBirds\n", + "\n", + "# Two erosions and two dilations to get rid of noise, and isolate bird structures.\n", + "birdsImage = scipy.ndimage.binary_erosion(birdsImage, struct, iterations=2).astype(birdsImage.dtype)\n", + "birdsImage = scipy.ndimage.binary_dilation(birdsImage, struct, iterations=2).astype(birdsImage.dtype)\n", + "\n", + "plotImage(birdsImage)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "18 birds have been detected.\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "labeled_array, num_features = scipy.ndimage.label(birdsImage)\n", + "\n", + "print(\"%d birds have been detected.\" % num_features)\n", + "\n", + "# Plotting with a colorful color-map so as to demonstrate the contiguous areas detected\n", + "plotImage(labeled_array, 'Paired')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/samples/MAXScript/macro-1.mcr b/samples/MAXScript/macro-1.mcr new file mode 100644 index 00000000..fff41b51 --- /dev/null +++ b/samples/MAXScript/macro-1.mcr @@ -0,0 +1,29 @@ +-- Taken from an example from Autodesk's MAXScript reference: +-- http://help.autodesk.com/view/3DSMAX/2016/ENU/?guid=__files_GUID_84E24969_C175_4389_B9A6_3B2699B66785_htm + +macroscript MoveToSurface + category: "HowTo" +( + fn g_filter o = superclassof o == Geometryclass + fn find_intersection z_node node_to_z = ( + local testRay = ray node_to_z.pos [0,0,-1] + local nodeMaxZ = z_node.max.z + testRay.pos.z = nodeMaxZ + 0.0001 * abs nodeMaxZ + intersectRay z_node testRay + ) + + on isEnabled return selection.count > 0 + + on Execute do ( + target_mesh = pickObject message:"Pick Target Surface:" filter:g_filter + + if isValidNode target_mesh then ( + undo "MoveToSurface" on ( + for i in selection do ( + int_point = find_intersection target_mesh i + if int_point != undefined then i.pos = int_point.pos + )--end i loop + )--end undo + )--end if + )--end execute +)--end script diff --git a/samples/MAXScript/macro-2.mcr b/samples/MAXScript/macro-2.mcr new file mode 100644 index 00000000..e0a897cf --- /dev/null +++ b/samples/MAXScript/macro-2.mcr @@ -0,0 +1,53 @@ +-- Taken from an example from Autodesk's MAXScript reference: +-- http://help.autodesk.com/view/3DSMAX/2016/ENU/?guid=__files_GUID_0876DF46_FAA3_4131_838D_5739A67FF2C1_htm + +macroscript FreeSpline category:"HowTo" tooltip:"FreeSpline" ( +local old_pos +local new_spline +local second_knot_set + +fn get_mouse_pos pen_pos old_pen_pos = ( + if old_pos == undefined then old_pos = old_pen_pos + if distance pen_pos old_pos > 10 then + ( + if second_knot_set then + addKnot new_spline 1 #smooth #curve pen_pos + else + ( + setKnotPoint new_spline 1 2 pen_pos + second_knot_set = true + ) + old_pos = pen_pos + updateShape new_spline + )-- end if +)-- end fn + +fn draw_new_line old_pen_pos = ( + pickPoint mouseMoveCallback:#(get_mouse_pos,old_pen_pos) +) + +undo"Free Spline"on( + new_spline = splineShape () + old_pen_pos = pickPoint () + + if old_pen_pos == #RightClick then + delete new_spline + else + ( + select new_spline + new_spline.pos = old_pen_pos + addNewSpline new_spline + addKnot new_spline 1 #smooth #curve old_pen_pos + addKnot new_spline 1 #smooth #curve old_pen_pos + second_knot_set = false + draw_new_line old_pen_pos + q = querybox "Close Spline?" title:"Free Spline" + if q then + ( + close new_spline 1 + updateshape new_spline + ) + select new_spline + )--end else +)--end undo +)--end script diff --git a/samples/MAXScript/svg-renderer.ms b/samples/MAXScript/svg-renderer.ms new file mode 100644 index 00000000..872334fe --- /dev/null +++ b/samples/MAXScript/svg-renderer.ms @@ -0,0 +1,64 @@ +-- Taken from a 3-part tutorial from Autodesk's MAXScript reference +-- Source: http://help.autodesk.com/view/3DSMAX/2016/ENU/?guid=__files_GUID_6B5EDC11_A154_4AA7_A972_A11AC36949E9_htm + +fn ColourToHex col = ( + local theComponents = #(bit.intAsHex col.r, bit.intAsHex col.g, bit.intAsHex col.b) + local theValue = "#" + for i in theComponents do + theValue += (if i.count == 1 then "0" else "") + i + theValue +) + +local st = timestamp() +local theFileName = (getDir #userscripts + "\\PolygonRendering3.svg") +local theSVGfile = createFile theFileName +format "\n" to:theSVGfile + +local theViewTM = viewport.getTM() +theViewTM.row4 = [0,0,0] + +local theViewTM2 = viewport.getTM() +local theViewSize = getViewSize() +local theViewScale = getViewSize() +theViewScale.x /= 1024.0 +theViewScale.y /= 1024.0 + +local theStrokeThickness = 3 + +gw.setTransform (matrix3 1) +for o in Geometry where not o.isHiddenInVpt and classof o != TargetObject do ( + local theStrokeColour = white + local theFillColour = o.wirecolor + + local theMesh = snapshotAsMesh o + for f = 1 to theMesh.numfaces do ( + local theNormal = normalize (getFaceNormal theMesh f) + + if (theNormal*theViewTM).z > 0 do + ( + local theFace = getFace theMesh f + local v1 = gw.transPoint (getVert theMesh theFace.x) + local v2 = gw.transPoint (getVert theMesh theFace.y) + local v3 = gw.transPoint (getVert theMesh theFace.z) + + v1.x /= theViewScale.x + v1.y /= theViewScale.y + v2.x /= theViewScale.x + v2.y /= theViewScale.y + v3.x /= theViewScale.x + v3.y /= theViewScale.y + + format "\t\n" (ColourToHex theStrokeColour) (ColourToHex theFillColour) theStrokeThickness to:theSVGfile + )--end if normal positive + )--end f loop +)--end o loop + +format "\n" to:theSVGfile +close theSVGfile +local theSVGMap = VectorMap vectorFile:theFileName alphasource:0 +local theBitmap = bitmap theViewSize.x theViewSize.y +renderMap theSVGMap into:theBitmap filter:true +display theBitmap +format "Render Time: % sec.\n" ((timestamp()-st)/1000.0) diff --git a/samples/MAXScript/volume-calc.ms b/samples/MAXScript/volume-calc.ms new file mode 100644 index 00000000..5e84e341 --- /dev/null +++ b/samples/MAXScript/volume-calc.ms @@ -0,0 +1,22 @@ +fn CalculateVolumeAndCentreOfMass obj = +( + local Volume= 0.0 + local Centre= [0.0, 0.0, 0.0] + local theMesh = snapshotasmesh obj + local numFaces = theMesh.numfaces + for i = 1 to numFaces do + ( + local Face= getFace theMesh i + local vert2 = getVert theMesh Face.z + local vert1 = getVert theMesh Face.y + local vert0 = getVert theMesh Face.x + local dV = Dot (Cross (vert1 - vert0) (vert2 - vert0)) vert0 + Volume+= dV + Centre+= (vert0 + vert1 + vert2) * dV + ) + delete theMesh + Volume /= 6 + Centre /= 24 + Centre /= Volume + #(Volume,Centre) +) diff --git a/vendor/grammars/language-maxscript b/vendor/grammars/language-maxscript new file mode 160000 index 00000000..a465c9ca --- /dev/null +++ b/vendor/grammars/language-maxscript @@ -0,0 +1 @@ +Subproject commit a465c9ca4adf71b8524021acb3cbe447db19753b