Skip to content

Latest commit

 

History

History
294 lines (263 loc) · 37.3 KB

README.md

File metadata and controls

294 lines (263 loc) · 37.3 KB

com-chilipeppr-widget-eagle

This widget lets you drag in an Eagle PCB ".brd" file to mill.

alt text

ChiliPeppr Widget / Eagle BRD v5.8

All ChiliPeppr widgets/elements are defined using cpdefine() which is a method that mimics require.js. Each defined object must have a unique ID so it does not conflict with other ChiliPeppr widgets.

Item Value
ID com-chilipeppr-widget-eagle
Name Widget / Eagle BRD v5.8
Description This widget lets you drag in an Eagle PCB ".brd" file to mill.
chilipeppr.load() URL http://raw.githubusercontent.com/ameennihad/widget-eagle/master/auto-generated-widget.html
Edit URL http://ide.c9.io/ameennihad/widget-eagle
Github URL http://github.com/ameennihad/widget-eagle
Test URL https://preview.c9users.io/ameennihad/widget-eagle/widget.html

Example Code for chilipeppr.load() Statement

You can use the code below as a starting point for instantiating this widget inside a workspace or from another widget. The key is that you need to load your widget inlined into a div so the DOM can parse your HTML, CSS, and Javascript. Then you use cprequire() to find your widget's Javascript and get back the instance of it.

// Inject new div to contain widget or use an existing div with an ID
$("body").append('<' + 'div id="myDivWidgetEagle"><' + '/div>');

chilipeppr.load(
  "#myDivWidgetEagle",
  "http://raw.githubusercontent.com/ameennihad/widget-eagle/master/auto-generated-widget.html",
  function() {
    // Callback after widget loaded into #myDivWidgetEagle
    // Now use require.js to get reference to instantiated widget
    cprequire(
      ["inline:com-chilipeppr-widget-eagle"], // the id you gave your widget
      function(myObjWidgetEagle) {
        // Callback that is passed reference to the newly loaded widget
        console.log("Widget / Eagle BRD v5.8 just got loaded.", myObjWidgetEagle);
        myObjWidgetEagle.init();
      }
    );
  }
);

Publish

This widget/element publishes the following signals. These signals are owned by this widget/element and are published to all objects inside the ChiliPeppr environment that listen to them via the chilipeppr.subscribe(signal, callback) method. To better understand how ChiliPeppr's subscribe() method works see amplify.js's documentation at http://amplifyjs.com/api/pubsub/

Signal Description
/com-chilipeppr-widget-eagle/onAddGcodeThis signal lets a 3rd party add-on inject its own Gcode into the overall final Gcode for the Eagle BRD Widget. Here is an example of how to subscribe.

chilipeppr.subscribe(
    "/com-chilipeppr-widget-eagle/addGcode", 
    this, 
    this.myOnAddGcode
    );
Then, your callback would look like this with 4 parameters receiving the variables that the addGcode publish signal sends you.

onAddGcode : function(addGcodeCallback, gcodeParts, eagleWidget, helpDesc){ 
    console.log("Got onAddGcode:", arguments); 
    // this method calls back to the main Eagle widget to inject our Gcode 
    addGcodeCallback(1500, myOwnGcode ); 
} 
The 1500 in the example above is to attach a priority to where our Gcode will get positioned. The base Gcode ends around line 900. The footer starts at line 2000. So putting our Gcode at the end but before the footer means using 1500 should do fine. You can analyze the existing Gcode by looking at parameter 2 gcodeParts to see if an index has already been used so you don't clobber it. If you want to delete Gcode from gcodeParts you could do that as well and the main widget will reflect the deletion.
/com-chilipeppr-widget-eagle/beforeLayerGenerateThis widget fires a signal before generating the Three.js objects and Clipper paths for a board layer. The Three.js objects are 3D objects representing the pads, vias, smds, wires, polygons, and dimensions. Those Three.js objects are used to populate the 3D viewer and to calculate 2D Clipper paths from.

Clipper paths are the 2D XY values of all the layer's objects and are generated so that unions and diffs can be calculated on those paths in the render step. Clipper paths can be easily inflated and deflated by the Clipper.js library which is why they are so important to this widget.

When you get this signal a reference to "this", i.e. the Eagle Widget, is included in the payload so you may use it to manipulate this widget as you see fit.
/com-chilipeppr-widget-eagle/afterLayerGeneratePlease see the /beforeLayerGenerate description to understand this signal better. The /afterLayerGenerate signal is fired after this widget is done generating the board layer. The payload is the same as the before signal.
/com-chilipeppr-widget-eagle/beforeToolPathRenderThis widget fires a signal before the rendering of the tool path for the milling of the Eagle BRD. As the user tests out different inflate values, you will get this signal for each re-render of the tool path the user asks for, i.e. when they click the "render" button.

In the payload is a reference to "this" so you can possibly grab info or do other manipulations of the board before we render the tool path. This is especially useful for add-on widgets to the Eagle BRD widget such as the Solder Paste Dispenser Add-On or the Pick and Place Add-On.
/com-chilipeppr-widget-eagle/afterToolPathRenderThis widget fires a signal after the rendering of the tool path for the Eagle BRD. The tool path is the blue line in the 3D viewer. Similar to the /beforeToolPathRender signal, in the payload is a reference to "this" so you can possibly grab info or do other manipulations of the board after we render. This is especially useful for add-on widgets to the Eagle BRD widget such as the Solder Paste Dispenser Add-On or the Pick and Place Add-On.

Subscribe

This widget/element subscribes to the following signals. These signals are owned by this widget/element. Other objects inside the ChiliPeppr environment can publish to these signals via the chilipeppr.publish(signal, data) method. To better understand how ChiliPeppr's publish() method works see amplify.js's documentation at http://amplifyjs.com/api/pubsub/

Signal Description
/com-chilipeppr-widget-eagle/getBoardDataCall this with a callback and you will immediately get back the baord data to your callback. Call like chilipeppr.publish("/com-chilipeppr-eagle/getBoardData", mycallback); This returns all of the board data for you, so that you can know all of the information that this Eagle BRD widget created. You will get back data like: { clipperBySignalKey: {}, // contains all signals (wires) clipperDimension: {}, // contains dimension of board clipperElements: {}, clipperPads: {}, // contains all pads (pads have holes) clipperSignalPolys: {}, // polygons that are signals like a GND plane clipperSignalWires: {}, // wires by name clipperSmds: {}, // all the smd pads, i.e. where components sit for soldering clipperVias: {}, // your vias. these have holes too. eagle: {}, // the parsed Eagle BRD XML into a structure }

Foreign Publish

This widget/element publishes to the following signals that are owned by other objects. To better understand how ChiliPeppr's subscribe() method works see amplify.js's documentation at http://amplifyjs.com/api/pubsub/

Signal Description
(No signals defined in this widget/element)

Foreign Subscribe

This widget/element publishes to the following signals that are owned by other objects. To better understand how ChiliPeppr's publish() method works see amplify.js's documentation at http://amplifyjs.com/api/pubsub/

Signal Description
/com-chilipeppr-widget-eagle/com-chilipeppr-elem-dragdrop/ondroppedWe subscribe to this signal at a higher priority to intercept the signal, double check if it is an Eagle Brd file and if so, we do not let it propagate by returning false. That way the 3D Viewer, Gcode widget, or other widgets will not get Eagle Brd file drag/drop events because they will not know how to interpret them.

Methods / Properties

The table below shows, in order, the methods and properties inside the widget/element.

Method / Property Type Description
idstring"com-chilipeppr-widget-eagle"

The ID of the widget. You must define this and make it unique.
namestring"Widget / Eagle BRD v5.8"
descstring"This widget lets you drag in an Eagle PCB \".brd\" file to mill."
urlstring"http://raw.githubusercontent.com/ameennihad/widget-eagle/master/auto-generated-widget.html"
fiddleurlstring"http://ide.c9.io/ameennihad/widget-eagle"
githuburlstring"http://github.com/ameennihad/widget-eagle"
testurlstring"http://widget-eagle-ameennihad.c9users.io/widget.html"
publishobjectPlease see docs above.

Define the publish signals that this widget/element owns or defines so that other widgets know how to subscribe to them and what they do.
subscribeobjectPlease see docs above.

Define the subscribe signals that this widget/element owns or defines so that other widgets know how to subscribe to them and what they do.
foreignPublishobjectPlease see docs above.

Document the foreign publish signals, i.e. signals owned by other widgets or elements, that this widget/element publishes to.
foreignSubscribeobjectPlease see docs above.

Document the foreign subscribe signals, i.e. signals owned by other widgets or elements, that this widget/element subscribes to.
initfunctionfunction (doMyOwnDragDrop)

All widgets should have an init method. It should be run by the instantiating code like a workspace or a different widget.

If you are doing development on this widget, it's important to understand what data is available to you after the board is parsed. This data can enable you to do enhanced operations. For example, I'm working on creating laser paths to laser out the solder mask to reveal the underlying pads and smds. I had to re-figure out what data is available to figure out those laser paths. Here's my summary. -Jlauer

Why clipper? Clipper is the library used to do boolean operations on polygons. Eagle gives us XY values for everything, and if we are to combine those into overall paths for milling, etc, then we need to merge those polygons. The clipper items below represent the clean final version of all that merging.

clipperBySignalKey: {}, // contains all signals (wires) clipperDimension: {}, // contains dimension of board clipperElements: {}, clipperPads: {}, // contains all pads (pads have holes) clipperSignalPolys: {}, // polygons that are signals like a GND plane clipperSignalWires: {}, // wires by name clipperSmds: {}, // all the smd pads, i.e. where components sit for soldering clipperVias: {}, // your vias. these have holes too. eagle: {}, // the parsed Eagle BRD XML into a structure
blankBoardobject
blankBoardSceneGroupobject
setupBlankBoardParamentersfunctionfunction ()
onChangeBlankBoardParamentersfunctionfunction ()
draw3dBlankBoardfunctionfunction ()
regHolesobject
regHoleGcodeParaobject
regHolesSceneGroupobject
setupRegHolesParamentersfunctionfunction ()
onChangeRegHolesGcodeParamentersfunctionfunction ()
onChangeRegHolesParamentersfunctionfunction ()
getRegHolesfunctionfunction ()
draw3dRegHolesfunctionfunction ()
exportGcodeRegistrationHolesfunctionfunction ()
sendRegHoleGcodeToWorkspacefunctionfunction ()
setupSolderMaskTabfunctionfunction ()

This sets up the tab to generate solder mask Gcode.
solderMaskRenderHidefunctionfunction ()
solderMaskGrpobject
solderMaskGcodePathobject
solderMaskRenderfunctionfunction ()

Look at all the pads/smds and render a path based on what the user gave us in the solder mask tab.
solderMaskRenderCallbackfunctionfunction ()
solderMaskRenderInvertfunctionfunction (opts)

This method renders an inverse path for lasering/milling. This can be used to expose a solder mask with UV laser light outside of the pads. Then the pads can be washed off to expose the copper.

opts = { width: w, isShowAsMesh: isShowAsMesh, isOutlineOnly: isOutlineOnly, outlineOut: outlineOut, outlineOn: outlineOn, outlineIn: outlineIn, gcodePath: this.solderMaskGcodePath, // threeGrp: this.solderMaskGrp, padsAndSmds: padsAndSmds, clipperDimension: this.clipperDimension, }
solderMaskRenderInvertCallbackfunctionfunction (opts)
solderMaskGenerateGcodeTimeoutPtrobject
solderMaskIsGcodeInRegeneratingStateboolean
solderMaskGenerateGcodefunctionfunction ()

This method will trigger a process to generateGcode however, it allows this to be called a bunch of times and it will always wait to do the generate about 1 second later and de-dupe the multiple calls.
solderMaskGenerateGcodeCallbackfunctionfunction ()

Iterate over the text3d that was generated and create Gcode to mill/cut the three.js object.
solderMaskSendGcodeToWorkspacefunctionfunction ()
drawPathAsLineOrMeshfunctionfunction (clipperPath, width, isShowAsMesh, threeGroup)

Pass in a clipper path and we will draw the line or inflate the line to a nice looking mesh. This is used to draw end mill paths that are the width of the line.
getCentroidfunctionfunction ( mesh )
mirrorXboolean
mirrorYboolean
setupMirrorAxisfunctionfunction ()
onChangeMirrorAxisfunctionfunction ()
tabsobject
setupTabParametersfunctionfunction ()
onChangeTabWidthfunctionfunction ()
onChangeTabHeightfunctionfunction ()
onChangeTabParameterfunctionfunction ()
setupLayerToggleDropdownfunctionfunction ()
populateLayerToggleDropdownfunctionfunction ()
onChangeLayerToggleDropdownfunctionfunction ()
ThreeAxisXobject
ThreeAxisYobject
ThreeAxisZobject
deg180toRadobject
setupFrequentThreeFeaturesfunctionfunction ()
setupFeedsDepthsfunctionfunction ()
calcPassesfunctionfunction (el)
activateWidgetfunctionfunction ()

This method is called from the main workspace telling us the user just activated us as a widget. This is not the same as load. Load happens once. Activate happens many times if user closes then opens us.
unactivateWidgetfunctionfunction ()
init3dfunctionfunction ()

Try to get a reference to the 3D viewer.
onInit3dSuccessfunctionfunction ()
obj3dobject
obj3dmetaobject
userCallbackForGet3dObjobject
get3dObjfunctionfunction (callback)
get3dObjCallbackfunctionfunction (data, meta)
is3dViewerReadyboolean
clear3dViewerfunctionfunction ()
clearEagleBrdfunctionfunction ()
clearEagleBrdStep2functionfunction ()
setupGcodeTabfunctionfunction ()
sendGcodeToWorkspacefunctionfunction ()
setupDragDropfunctionfunction ()
eagleobject
openfunctionfunction (data, info)
draw3dfunctionfunction (callback)

We need the 3D viewer to be ready to go for us to generate our 3D view, so do a little bit of a wait sequence here where we try 3 times to grab the 3D viewer object and then we can render our board. Alternately, we could render our board and then inject into the 3D viewer later. Not sure why I didn't do it that way initially.
colorSignalnumber
colorSmdnumber
colorSignalBottomnumber
colorSmdBottomnumber
colorVianumber
colorPadnumber
colorMillnumber
colorHolenumber
colorHoleUnhandlednumber
colorsDropobject
colorDimensionnumber
colorTabsnumber
colorMillingnumber
colorFailednumber
opacitySignalnumber
opacityDimensionnumber
opacityTabsnumber
opacityVianumber
opacityPadnumber
endmillSizenumber
actualEndmillnumber
inflateMillPathByobject
pathsobject
pathsUnionobject
pathsUnionHolesobject
boardBoundariesobject
blankBoundariesobject
activeLayerstring"Top"
clipperDimensionsobject
onDraw3dReadyfunctionfunction ()

This is a key method that will actually start the traversal of the entire Eagle BRD and generate Three.js objects for each pad/smd/via/wire, etc. Then it will generate Clipper Paths which are just 2d xy values in the format that the Clipper library wants so we can do unions and diffs which is important to generate the isolation paths as well as deal with polygons that may be on the board representing signal planes like a GND plane.
onDraw3dReadyAfterfunctionfunction ()
clearanceHeightnumber
depthOfSignalMillingnumber
feedRatePlungenumber
feedRateSignalsnumber
feedRateDimensionsnumber
drillFeedratenumber
drillMaxDiameternumber
drillDepthnumber
depthOfDimensionsnumber
millDiameternumber
millDiameterMinnumber
useDimensionLayerboolean
useMillingLayerboolean
cuttingToolOptionnumber
minWireWidthToMillnumber
ignoreSmallWiresboolean
stepDownDimensionsnumber
stepDownPassesnumber
spindleRPMnumber
exportGcodeHeaderfunctionfunction ()
exportGcodeMillingfunctionfunction ()
exportGcodeMarkHolesfunctionfunction ()
exportGcodeDrillHolesfunctionfunction ()
exportGcodeMillHolesfunctionfunction ()
getBoardDimensionsToMillfunctionfunction ()

This function will create inflate/deflate board dimension paths without using ClipperLib the resulting path(s) will be an array of lines and curves, this was necessary to implement the Tabs feature introduced in V5.4, as a redults curves will be rendered as G02/G03 gcode command.
fixAnglefunctionfunction (angle)
exportGcodeDimensionsfunctionfunction ()
getDimensionGcodefunctionfunction (v2, v1, z, isOpen, curve)
roundfunctionfunction (n)
exportGcodeFooterfunctionfunction ()
exportGcodefunctionfunction ()
gcodePartsobject
addGcodefunctionfunction (count, gcode)
getGcodefunctionfunction ()
setupAdvancedInflateByUIfunctionfunction ()
onFullRefreshfunctionfunction (event, callback)
onRefreshfunctionfunction (event, callback)
threePathEndMillobject
onRefresh2ndfunctionfunction (event, callback)
getInflatePathWithConstraintfunctionfunction (paths, inflateBy, constraints)
raycasterobject
projectorobject
arrowHelperobject
intersectObjectsobject
renderAreaobject
infoAreaobject
infoSignalAreaobject
lastIntersectobject
hidePopupsElemobject
setupMouseOverfunctionfunction ()
reactivateMouseMovefunctionfunction ()
deactivateMouseMovefunctionfunction ()
hidePopupsfunctionfunction ()
lastIntersectOtherMaterialsobject
onMouseOverfunctionfunction (event)
getXorOfClipperPathsfunctionfunction (subj_paths, clip_paths)
getIntersectionOfClipperPathsfunctionfunction (subj_paths, clip_paths)
getDiffOfClipperPathsfunctionfunction (subj_paths, clip_paths)
getAllPathsAsOuterOrientationfunctionfunction (subj_paths)
getUnionOfClipperPathsfunctionfunction (subj_paths)
drawUnionOfClipperPathsfunctionfunction (subj_paths)
getPadGeometryIntersectedWithPolygonfunctionfunction (polygons, lineGeo, layerNumber)
unionLineGeometriesIfIntersectedfunctionfunction (lineGeo1, lineGeo2)
drawClipperPathsfunctionfunction (paths, color, opacity, z, zstep, isClosed, isAddDirHelper)
createClipperPathsAsMesh_XXXfunctionfunction (paths, color, opacity, holePath)
createClipperPathsAsMeshfunctionfunction (paths, color, opacity, holePath, depth)
getMeshLineFromClipperPathfunctionfunction (opts)

This method is used to show the milling/laser path of a line by creating a cyan mesh of the width of the line. You pass in the line as a Clipper Path. That means we treat the Clipper polygon as if it's the trace line. opts = { width: 1, // width of line clipperPath: [[]], // typical array of array isSolid: true, // if false then just shows outline color: 0x0000ff, // blue default opacity: 0.3, // 0 transparent to 1 non-transparent } Returns: THREE.Group of meshes
getInflatePathfunctionfunction (paths, delta, joinType)

Enormously useful function to inflate or deflate clipper paths. Pass in the array of array like all normal clipper dimensions are. Then pass in a pos/neg number for how much to inflate or deflate by. So to inflate by 0.5mm then pass in 0.5. To deflate 0.8mm pass in -0.8. For joinType the default is ClipperLib.JoinType.jtRound. See ClipperLib docs for joinType or leave empty.
getInflateOpenPathfunctionfunction (paths, delta, joinType)
createThermalCutoutsFromSmdfunctionfunction (smd, poly, myInflateBy)
sortObjByKeyfunctionfunction (obj)
adjustPathfunctionfunction (path, rotation, positionX, positionY)
wiresConnectedfunctionfunction (w1, w2)
wiresConnectedFfunctionfunction (w1, w2)
wiresConnectedBfunctionfunction (w1, w2)
clipperDimensionobject
buildDimensionClipperfunctionfunction ()
draw3dDimensionfunctionfunction ()
draw3dTabsfunctionfunction ()
getTabMeshfunctionfunction (width, d)
addStrokeCapsToLinefunctionfunction (x1, y1, x2, y2, width, capType)
clipperBySignalKeyobject
clipperBySignalKeyItemobject
clipperSignalWiresobject
clipperSignalPolysobject
draw3dHolesfunctionfunction ()//V5.2D20170105 Added
draw3dViasfunctionfunction (layersName)
draw3dSignalWiresfunctionfunction (layer)
draw3dSignalPolygonsfunctionfunction (layer)
clipperElementsobject
clipperPadsobject
clipperSmdsobject
clipperViasobject
holesToDrillobject
holesToMillobject
holesUnhandledCountnumber
addHolefunctionfunction (drill, x, y)//V5.2D20170105 Added
draw3dElementsfunctionfunction (layer)
rotObjectMatrixobject
rotateAroundObjectAxisfunctionfunction (object, axis, radians)
rotWorldMatrixobject
rotateAroundWorldAxisfunctionfunction (object, axis, radians)
boundriesfunctionfunction ()
flipXfunctionfunction (x)

Recalculate value of X if board is being mirrored
flipYfunctionfunction (y)

Recalculate value of Y if board is being mirrored
flipObject3Dfunctionfunction (o)

Mirror Object3D (smdgroups and padgroups) if board is being mirrored this function must be called before setting the position of the group
drawCirclefunctionfunction (x, y, radius, color, seg, opacity)
drawSquare2functionfunction (x, y, w, color)
getCurveParametersfunctionfunction (x1, y1, x2, y2, curve)
drawArcfunctionfunction (x1, y1, x2, y2, curve, color)
createCurvePointsfunctionfunction (x1, y1, x2, y2, curve)
createArcPointsfunctionfunction (aX, aY, radius, aStartAngle, aEndAngle)
drawSpherefunctionfunction (x, y, radius, color)
drawSquarefunctionfunction (x1, y1, x2, y2)
mySceneGroupobject
sceneReAddMySceneGroupfunctionfunction ()
sceneRemoveMySceneGroupfunctionfunction ()
sceneAddfunctionfunction (obj)
sceneRemovefunctionfunction (obj)
drawfunctionfunction (e)
onDroppedfunctionfunction (data, info)
onDragOverfunctionfunction ()
onDragLeavefunctionfunction ()
isVidLoadedboolean
lazyLoadTutorialfunctionfunction ()
optionsobject
setupUiFromLocalStoragefunctionfunction ()
saveOptionsLocalStoragefunctionfunction ()
showBodyfunctionfunction (evt)
hideBodyfunctionfunction (evt)
btnSetupfunctionfunction ()
statusElobject
statusfunctionfunction (txt)
forkSetupfunctionfunction ()

About ChiliPeppr

ChiliPeppr is a hardware fiddle, meaning it is a website that lets you easily create a workspace to fiddle with your hardware from software. ChiliPeppr provides a Serial Port JSON Server that you run locally on your computer, or remotely on another computer, to connect to the serial port of your hardware like an Arduino or other microcontroller.

You then create a workspace at ChiliPeppr.com that connects to your hardware by starting from scratch or forking somebody else's workspace that is close to what you are after. Then you write widgets in Javascript that interact with your hardware by forking the base template widget or forking another widget that is similar to what you are trying to build.

ChiliPeppr is massively capable such that the workspaces for TinyG and Grbl CNC controllers have become full-fledged CNC machine management software used by tens of thousands.

ChiliPeppr has inspired many people in the hardware/software world to use the browser and Javascript as the foundation for interacting with hardware. The Arduino team in Italy caught wind of ChiliPeppr and now ChiliPeppr's Serial Port JSON Server is the basis for the Arduino's new web IDE. If the Arduino team is excited about building on top of ChiliPeppr, what will you build on top of it?