cad port 1/3
This commit is contained in:
parent
88449f52c9
commit
76f2452e98
449
packages/cad/.vscode/launch.json
vendored
Normal file
449
packages/cad/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,449 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test - Drive - HTML",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=false",
|
||||
"--dry=false",
|
||||
"--logLevel=trace",
|
||||
"--configuration=test",
|
||||
"--src='./tests/drive/400*.+(SLDASM)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}-${CONFIGURATION}.+(html)'"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test - Edrawings",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=true",
|
||||
"--dry=false",
|
||||
"--debug=true",
|
||||
"--verbose=true",
|
||||
"--src='./tests/html/*.+(SLDASM|SLDPRT)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}.+(html)'"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test - Drive - BOM",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=false",
|
||||
"--dry=false",
|
||||
"--debug=true",
|
||||
"--verbose=true",
|
||||
"--src='./tests/drive/*.+(SLDASM)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}.+(xlsx)'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test - Pack - Cabinet",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=false",
|
||||
"--pack=true",
|
||||
"--logLevel=debug",
|
||||
"--src='./tests/cabinet/vintage*.+(SLDASM)'",
|
||||
"--dst='${SRC_DIR}/packed'"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test:Drive:JSON",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=false",
|
||||
"--logLevel=trace",
|
||||
"--src='./tests/drive/*.+(SLDASM)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}.+(json)'"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test - ModelReader - Lydia36",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=true",
|
||||
"--dry=false",
|
||||
"--debug=true",
|
||||
"--verbose=true",
|
||||
"--src='${OSR_ROOT}/products/products/extrusion/lydia-v3.5/cad/*Global*.+(SLDASM)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}.+(json)'"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test - Drive - Props - Cas",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=true",
|
||||
"--dry=false",
|
||||
"--debug=true",
|
||||
"--verbose=true",
|
||||
"--src='./tests/cas/Global*.+(SLDASM)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}.+(json)'"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test - Drive - STEP",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--debug=true",
|
||||
"--hidden=false",
|
||||
"--verbose=true",
|
||||
"--src='./tests/drive/*.+(SLDASM)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}.+(jpg)'"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test - Drive - JPG - PhotoView",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=true",
|
||||
"--dry=false",
|
||||
"--debug=true",
|
||||
"--verbose=true",
|
||||
"--src='./tests/drive/*.+(SLDASM)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}.+(jpg)'"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test - CAS - STEP:NoEnclosure",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=true",
|
||||
"--dry=false",
|
||||
"--debug=true",
|
||||
"--verbose=true",
|
||||
"--src='./tests/cas/cad/Global*.+(SLDASM)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}.+(step)'",
|
||||
//"--configuration='NoEnclosure'"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test - CAS - STEP: All Configurations",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=true",
|
||||
"--dry=false",
|
||||
"--debug=true",
|
||||
"--verbose=true",
|
||||
"--src='./tests/cas/cad/Global*.+(SLDASM)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}-${CONFIGURATION}.+(step|html)'"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test - Flexibot - STEP: All Configurations",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=true",
|
||||
"--dry=false",
|
||||
"--debug=true",
|
||||
"--verbose=true",
|
||||
"--src='${OSR_ROOT}/flexi-bot/cad/storch-150/cad/Global*.+(SLDASM)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}-${CONFIGURATION}.+(step)'"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test - Drive - Configrations",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=true",
|
||||
"--dry=false",
|
||||
"--debug=true",
|
||||
"--verbose=true",
|
||||
"--src='./tests/drive/*.+(SLDASM)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}-configs.+(json)'"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test - CAS - Configrations to HTML",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=true",
|
||||
"--dry=false",
|
||||
"--debug=true",
|
||||
"--verbose=true",
|
||||
"--src='./tests/cas/cad/Global*.+(SLDASM)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}-${CONFIGURATION}.+(html)'"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test Alt - Drive - JSON",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=true",
|
||||
"--dry=false",
|
||||
"--debug=true",
|
||||
"--verbose=true",
|
||||
"--alt=true",
|
||||
"--src='./tests/drive/*.+(SLDASM)'",
|
||||
"--dst='&{SRC_DIR}/&{SRC_NAME}.+(json)'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test PRoot/Katbot - JSON",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=true",
|
||||
"--dry=false",
|
||||
"--debug=true",
|
||||
"--verbose=true",
|
||||
"--alt=false",
|
||||
"--src='${PRODUCT_ROOT}/products/injection/katbot/cad/Global*.+(SLDASM)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}.+(json)'"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test PRoot/SPRCB650 - JSON",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"sw",
|
||||
"--cache=true",
|
||||
"--dry=false",
|
||||
"--debug=true",
|
||||
"--verbose=true",
|
||||
"--alt=false",
|
||||
"--src='${PRODUCT_ROOT}/products/sheetpress/sheetpress-cell-rcA-x/cad/Global*.+(SLDASM)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}.+(json)'"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test - Slice",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"slice",
|
||||
"--cache=false",
|
||||
"--dry=false",
|
||||
"--debug=true",
|
||||
"--verbose=true",
|
||||
"--src='./tests/print/Global*.+(3mf)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}.+(gcode)'",
|
||||
"--saveAsProfile='${SRC_DIR}/profile.json'",
|
||||
"--profile='${SRC_DIR}/profile.json'",
|
||||
"--saveArgs='${SRC_DIR}/slice.sh'",
|
||||
"--log='${SRC_DIR}/last.log'",
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test - Slice - Profiles",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}//**/*.js"
|
||||
],
|
||||
"args": [
|
||||
"slice",
|
||||
"--cache=false",
|
||||
"--dry=false",
|
||||
"--debug=true",
|
||||
"--verbose=true",
|
||||
"--src='./tests/print/Global*.+(3mf)'",
|
||||
"--dst='${SRC_DIR}/${SRC_NAME}.+(gcode)'",
|
||||
"--saveAsProfile='${SRC_DIR}/profile.json'",
|
||||
"--profile='${OSR_PROFILES}/print/tests/profile.json'",
|
||||
"--saveArgs='${SRC_DIR}/slice.sh'",
|
||||
"--log='${SRC_DIR}/last.log'",
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
6
packages/cad/.vscode/settings.json
vendored
Normal file
6
packages/cad/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"Solidwork"
|
||||
],
|
||||
"cmake.configureOnOpen": false
|
||||
}
|
||||
24
packages/cad/LICENSE
Normal file
24
packages/cad/LICENSE
Normal file
@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <https://unlicense.org>
|
||||
214
packages/cad/README.md
Normal file
214
packages/cad/README.md
Normal file
@ -0,0 +1,214 @@
|
||||
# OSR CAD Tools
|
||||
|
||||
This is a CLI(CommandLineInterface) toolset to convert 3D files, using Solidworks and other software.
|
||||
|
||||
## Requirements
|
||||
|
||||
1. [Node-JS](https://nodejs.org/en/download/)
|
||||
2. Optional: install [Git](https://git-scm.com/downloads) (Make sure you enable Linux tools on Windows console)
|
||||
3. Solidworks 2020. In case you are using another version, please find on your disc 'SolidWorks.Interop.sldworks.dll' and replace the one in [./sw/2022](https://git.osr-plastic.org/osr-plastic/osr-cad/src/branch/master/sw/2022)
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
|
||||
git clone https://git.osr-plastic.org/osr-plastic/osr-cad.git
|
||||
cd osr-convert-cad
|
||||
npm i
|
||||
|
||||
# or globally (recommended)
|
||||
|
||||
npm i @plastichub/osr-cad -g
|
||||
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Open a terminal and run this:
|
||||
|
||||
```sh
|
||||
osr-cad --help
|
||||
```
|
||||
|
||||
See more in [./docs/Examples.md](./docs/Examples.md) and [./docs/Integration.md](./docs/Integration.md)
|
||||
|
||||
### References - Development
|
||||
|
||||
- [site:Solidworks API basics - examples](https://www.codestack.net/labs/solidworks/)
|
||||
- [site:Rhino-API](https://developer.rhino3d.com/api/RhinoCommon/html/R_Project_RhinoCommon.htm)
|
||||
- [site:Solidworks Reverse Decoder](http://heybryan.org/solidworks_file_format.html)
|
||||
- [sw interop - component - API ](https://help.solidworks.com/2019/English/api/swdocmgrapi/Get_Current_Name_of_Configuration_of_Suppressed_Component_Example_CSharp.htm)
|
||||
|
||||
## Todos
|
||||
|
||||
- [x] Select default views via CLI Argument
|
||||
- [ ] Arg: Skip suppressed | hidden (difficult since it's out of part file scope, check explorer api ) | dry mode
|
||||
- [x] Arg: Overwrite files
|
||||
- [-] Arg: skip non OSR parts
|
||||
- [-] Arg: displaymode : wireframe, shaded, ... (see [SW Docs](http://help.solidworks.com/2017/english/api/sldworksapi/solidworks.interop.sldworks~solidworks.interop.sldworks.iview~setdisplaymode3.html))
|
||||
- [-] report
|
||||
- [x] export as lib
|
||||
- [-] Multi view (trainings data for @plastichub/part-detector)
|
||||
- [-] Speed: use same instance for multiple exports
|
||||
- [-] Context Menu Shell Extension (@osr-tools)
|
||||
- [-] Local/Global config (=>osrl)
|
||||
- [ ] emit/merge authors from components in target artefact
|
||||
- [-] Add CLI Arg Path variables
|
||||
- [-] json-path for glob patterns
|
||||
- [-] bracket expansion
|
||||
- [-] Report templates (=> @osrl | osr-reports)
|
||||
- [ ] xls
|
||||
- [ ] md
|
||||
- [ ] txt
|
||||
- [ ] json
|
||||
- [ ] meta | ts | tree
|
||||
- [-] Plugin interface for custom format (chained) => osrl
|
||||
- [x] Conversions
|
||||
- [x] STEP -> SLDPRT (via xcad->fc->fw)
|
||||
- [x] any -> 3dxml (osrl!)
|
||||
- [x] any -> html (via edrawings)
|
||||
- [ ] Structural
|
||||
- [ ] support pipes, eg: intermediate formats
|
||||
- [-] add pre, post and content filters, as pipes
|
||||
- [-] plugins
|
||||
- [-] integrate osrl
|
||||
- [-] omit format options in --help
|
||||
- [ ] omit possible conversions in ```info``
|
||||
- [ ] per in and out args
|
||||
- [ ] global
|
||||
- [-] Cache hash fuckery : integrate options in integrity
|
||||
- [ ] external cache directory
|
||||
- [ ] bom|html|props : configurations
|
||||
- [ ] explicit cache directory
|
||||
|
||||
### Commands - Todos - Solidworks
|
||||
|
||||
- [x] Solidworks
|
||||
- [-] Set system wide options for JPG output
|
||||
- [-] Set system wide options for PDF output
|
||||
- [-] Directory index (=>osrl)
|
||||
- [ ] arg: local HTML path/dir offset
|
||||
- [ ] arg: generate UNC paths
|
||||
- [ ] format: PDF
|
||||
- [-] arg: sw drawing/BOMs to CSV/xls
|
||||
- [-] Part/Sub-Assembly web(&local) compilation/index (=>osrl)
|
||||
- [-] Web directory ([xeokit](https://gitlab.com/plastichub/osr/xeokit-sdk))
|
||||
- [-] Git hook, check components & references
|
||||
- [x] move 2D formats to osr-media
|
||||
- [-] implement osr-cli-common specs: info/introspect|supported
|
||||
- [x] root offset
|
||||
- [x] sw:info|bom -> i18n
|
||||
- [ ] remove toolbox write protection (sldsetdocprop.exe | https://www.youtube.com/watch?v=N7_HSvWPAXw | https://help.solidworks.com/2022/english/api/swdocmgrapi/SolidWorks.Interop.swdocumentmgr~SolidWorks.Interop.swdocumentmgr.ISwDMDocument~ToolboxPart.html)
|
||||
- [-] sw: catch read errors
|
||||
- [ ] sw: migrate xcad latest
|
||||
- [ ] sw: addons - API (disable, ..)
|
||||
- [-] sw: model-reader : iterator | filter | findup-references
|
||||
- [-] sw: bom : filter & map
|
||||
- [-] sw: set properties | save-as, ...
|
||||
- [ ] sw: osr-log
|
||||
- [ ] sw: sub commands: convert | validate | pack | set | get | clean | render | tree (cp/mv/rm) | unlink
|
||||
- [x] get: configurations -> json
|
||||
- [x] convert(conf) -> model
|
||||
- [x] render(conf) -> image
|
||||
- [ ] validate
|
||||
- [-] internal files
|
||||
- [ ] outside root / component
|
||||
- [ ] naming conventions
|
||||
- [-] default configurations
|
||||
- [ ] sw errors
|
||||
- [ ] library compat
|
||||
- [-] orphan files
|
||||
- [-] equations
|
||||
- [ ] tree
|
||||
- [ ] md
|
||||
- [x] json
|
||||
- [ ] fs
|
||||
- [-] xls
|
||||
- [ ] osr-i8n
|
||||
- [ ] walker -> piped
|
||||
- [ ] orphans (incl. assets / maps)
|
||||
- [x] sw: render : renderers (+options)
|
||||
- [x] sw: render
|
||||
- [-] scene defaults
|
||||
- [ ] motion analysis
|
||||
- [x] query(tree)
|
||||
- [ ] sw: explode
|
||||
- [ ] sw: timeouts
|
||||
- [x] sw: osr-default props
|
||||
- [-] sw: cache instance (node IPC | csharp JIT?)
|
||||
- [x] sw: cache
|
||||
- [x] meta: diff
|
||||
- [ ] invalidate
|
||||
- [-] mv
|
||||
- [ ] pack / unpack
|
||||
- [ ] versioning
|
||||
- [ ] packages
|
||||
- [ ] registry
|
||||
- [ ] shared equations (design table alternative) -> osrl | equation templates
|
||||
- [ ] sketch / block templates
|
||||
|
||||
### Commands - Todos - SCad
|
||||
|
||||
- [ ] impl. basic verbs: convert (see https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Using_OpenSCAD_in_a_command_line_environment)
|
||||
|
||||
### Lib - Todos
|
||||
|
||||
- [-] SW: 4 view single image
|
||||
- [-] Incorrect JPG output with sw2020
|
||||
|
||||
### Utils
|
||||
|
||||
- [Batch Export to HTML via EDrawings OCX](ref/edrawings-api/BatchExportHTML)
|
||||
|
||||
- For SOLIDWORKS Document Manager API, please check the intro [here](https://www.codestack.net/solidworks-document-manager-api/) which leads to [https://xcad.xarial.com/]. Their actual API code is now at [./ref/xcad](./ref/xcad). Please check also [xcad basics on YouTube](https://www.youtube.com/watch?v=dLjlTYYeMpo)
|
||||
|
||||
### Resources - Solidworks
|
||||
|
||||
- [Custom Properties Write API](https://help.solidworks.com/2017/english/api/sldworksapi/change_configuration_properties_example_vb.htm)
|
||||
- [XCad Github](https://github.com/xarial/xcad.git)
|
||||
- [SOLIDWORKS](https://www.linkedin.com/company/solidworks?trk=public_post_share-update_update-text)
|
||||
- [SW Model Error Ref](https://help.solidworks.com/2019/english/api/swconst/SO_Messages.htm)
|
||||
- API Help Files [https://lnkd.in/d9QX6wvS](https://lnkd.in/d9QX6wvS?trk=public_post_share-update_update-text)
|
||||
- Free API Books, Macros and Utilities by [Luke Malpass](https://uk.linkedin.com/in/angelsix?trk=public_post_share-update_update-text) - [https://lnkd.in/d8EbSDiB](https://lnkd.in/d8EbSDiB?trk=public_post_share-update_update-text)
|
||||
- Video Tutorials (first few lessons are free and rest are paid) by [SolidProfessor](https://www.linkedin.com/company/solidprofessor?trk=public_post_share-update_update-text)
|
||||
- [https://lnkd.in/d6bJew-z](https://lnkd.in/d6bJew-z?trk=public_post_share-update_update-text)
|
||||
- [https://lnkd.in/dAv2366P](https://lnkd.in/dAv2366P?trk=public_post_share-update_update-text)
|
||||
- [Artem Taturevych](https://au.linkedin.com/in/artem-taturevych?trk=public_post_share-update_update-text)’s free SOLIDWORKS Goodies
|
||||
- [http://www.codestack.net](http://www.codestack.net/?trk=public_post_share-update_update-text)/
|
||||
- [Lenny Kikstra](https://www.linkedin.com/in/lennyworks?trk=public_post_share-update_update-text)
|
||||
- free SOLIDWORKS Goodies [https://lnkd.in/d6RJfCuZ](https://lnkd.in/d6RJfCuZ?trk=public_post_share-update_update-text)
|
||||
- [Roland Schwarz](https://www.linkedin.com/in/rolandschwarz?trk=public_post_share-update_update-text)
|
||||
- free SOLIDWORKS Goodies [https://lnkd.in/dSiq6r6h](https://lnkd.in/dSiq6r6h?trk=public_post_share-update_update-text)
|
||||
- Video Tutorials (free and paid with macros library) by [Keith Rice](https://www.linkedin.com/in/keitharice?trk=public_post_share-update_update-text)
|
||||
- [https://www.cadsharp.com](https://www.cadsharp.com/?trk=public_post_share-update_update-text)
|
||||
- MySolidWorks Video Training (paid) [https://lnkd.in/dpXnNBsy](https://lnkd.in/dpXnNBsy?trk=public_post_share-update_update-text)
|
||||
- SOLIDWORKS Free Macros at Cadforum: [https://lnkd.in/d4W63jBX](https://lnkd.in/d4W63jBX?trk=public_post_share-update_update-text)
|
||||
- SOLIDWORKS Free Macros at 3D Content Central: [https://lnkd.in/d4zVEfhh](https://lnkd.in/d4zVEfhh?trk=public_post_share-update_update-text) • SOLIDWORKS Customization eBook using VB.Net (paid) by [Tushar Suradkar](https://in.linkedin.com/in/tusharsuradkar?trk=public_post_share-update_update-text)
|
||||
- [https://lnkd.in/dD_sn3ai](https://lnkd.in/dD_sn3ai?trk=public_post_share-update_update-text)
|
||||
- [Mike Spens](https://www.linkedin.com/in/mikespens?trk=public_post_share-update_update-text)
|
||||
- API resources [http://www.solidapi.com](http://www.solidapi.com/?trk=public_post_share-update_update-text)/ and book (paid) by him "Automating SOLIDWORKS Using Macros" ([https://amzn.to/3nWOmYn](https://amzn.to/3nWOmYn?trk=public_post_share-update_update-text))
|
||||
- Stefan Berlitz's free SOLIDWORKS Goodies [https://lnkd.in/dMCmnX6h](https://lnkd.in/dMCmnX6h?trk=public_post_share-update_update-text)
|
||||
- SOLIDWORKS users on active subscription also have access to two API SolidPractices available from [https://lnkd.in/d9VD3f5A](https://lnkd.in/d9VD3f5A?trk=public_post_share-update_update-text)
|
||||
- Free SOLIDWORKS API [VBA + C#] Tutorials from [Prashant Baher](https://in.linkedin.com/in/prashantbaher?trk=public_post_share-update_update-text) [https://thecadcoder.com](https://thecadcoder.com/?trk=public_post_share-update_update-text)/
|
||||
- Video Tutorials by [GoEngineer](https://www.linkedin.com/company/goengineer?trk=public_post_share-update_update-text) [https://lnkd.in/gfBKmeU4](https://lnkd.in/gfBKmeU4?trk=public_post_share-update_update-text)
|
||||
- SOLIDWORKS forums to ask/find great solutions/macros 3DSwym SOLIDWORKS User Forum: [https://lnkd.in/dFG_isCJ](https://lnkd.in/dFG_isCJ?trk=public_post_share-update_update-text)
|
||||
- Eng-Tips: [https://lnkd.in/dgspDQ-H](https://lnkd.in/dgspDQ-H?trk=public_post_share-update_update-text)
|
||||
- CadOverFlow: [https://lnkd.in/d3bFWXUb](https://lnkd.in/d3bFWXUb?trk=public_post_share-update_update-text)
|
||||
|
||||
### XEO
|
||||
|
||||
- https://github.com/xeokit/xeokit-convert
|
||||
|
||||
### Free - CAD
|
||||
|
||||
- https://forum.freecadweb.org/viewtopic.php?p=556013#p556013
|
||||
- https://hub.docker.com/r/amrit3701/freecad-cli
|
||||
- https://wiki.opensourceecology.org/wiki/FreeCAD_BOM_Generator
|
||||
|
||||
### GEO
|
||||
|
||||
- https://macwright.com/2023/11/13/placemark
|
||||
|
||||
### Exce Build Dependencies for 'nexe'
|
||||
|
||||
- [NASM](https://www.nasm.us/pub/nasm/releasebuilds/2.16rc12/win64/)
|
||||
5
packages/cad/config.json
Normal file
5
packages/cad/config.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variables":{
|
||||
"OSR_CAD_WEB":"https://osr-plastic.org/cad"
|
||||
}
|
||||
}
|
||||
170
packages/cad/docs/Examples.md
Normal file
170
packages/cad/docs/Examples.md
Normal file
@ -0,0 +1,170 @@
|
||||
### General usage
|
||||
|
||||
```sh
|
||||
osr-cad sw --src=(FOLDER||FILE)/GLOB --dst=EXPRESSION||FILE||FOLDER/GLOB
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
**src** : The source directory or file. This can be a glob pattern.
|
||||
|
||||
**dst** : The source directory or file. This can be a glob pattern with expressions.
|
||||
|
||||
**configuration** : The model configuration
|
||||
|
||||
### Variables
|
||||
|
||||
|
||||
**SRC_DIR** : The directory of the current file being converted
|
||||
|
||||
**SRC_NAME** : The file name of the current file being converted
|
||||
|
||||
**SRC_FILE_EXT** : The file extension of the current file being converted
|
||||
|
||||
## Basics
|
||||
|
||||
### Convert all assembly files to PDF files in the current directory
|
||||
|
||||
```sh
|
||||
osr-cad sw --src='../plastichub/products/elena/cad/*.SLDASM' --dst='${SRC_NAME}.pdf'
|
||||
```
|
||||
### Convert all assembly files to PDF files in the source directory
|
||||
|
||||
```sh
|
||||
osr-cad sw --src='../plastichub/products/elena/cad/*.SLDASM' --dst='${SRC_DIR}/${SRC_NAME}.pdf'
|
||||
```
|
||||
|
||||
### Convert all assembly files to PDF files in the source directory, recursively
|
||||
|
||||
**Note** : Recursion can be added by using `**/`.
|
||||
|
||||
```sh
|
||||
osr-cad sw --src='../plastichub/products/elena/cad/**/*.SLDASM' --dst='${SRC_DIR}/${SRC_NAME}.pdf'
|
||||
```
|
||||
|
||||
### Convert all assembly and part files to PDF files in the source directory, recursively
|
||||
|
||||
**Note** : Recursion can be added by using `**/`.
|
||||
|
||||
**Note** : To select or use multiple file extensions, write ```*.+(SLDASM|SLDPRT)``` instead of ```*.SLDASM```
|
||||
|
||||
```sh
|
||||
osr-cad sw --src='../plastichub/products/elena/cad/**/*.+(SLDASM|SLDPRT)' --dst='${SRC_DIR}/${SRC_NAME}.pdf'
|
||||
```
|
||||
|
||||
### Convert all assembly and part files to PDF and JPG files in the source directory, recursively
|
||||
|
||||
**Note** : Recursion can be added by using `**/`.
|
||||
|
||||
**Note** : To select or use multiple file extensions, write ```*.+(SLDASM|SLDPRT)``` instead of ```*.SLDASM```
|
||||
|
||||
```sh
|
||||
osr-cad sw --src='../plastichub/products/elena/cad/**/*.+(SLDASM|SLDPRT)' --dst='${SRC_DIR}/${SRC_NAME}.+(pdf|jpg)'
|
||||
```
|
||||
|
||||
### Convert all assembly files to STEP and PDF files in the source directory
|
||||
|
||||
```sh
|
||||
osr-cad sw --src='./products/asterix-pp/cad/*.+(SLDASM)' --dst='${SRC_DIR}/${SRC_NAME}.+(step|pdf)'
|
||||
```
|
||||
|
||||
### Extra all custom properties and depending parts from assembly files to JSON files in the source directory
|
||||
|
||||
```sh
|
||||
osr-cad sw --src='./products/asterix-pp/cad/*.+(SLDASM)' --dst='${SRC_DIR}/${SRC_NAME}.+(json)'
|
||||
```
|
||||
|
||||
### Convert parts or assemblies to HTML files (all incl. view and data) - using eDrawings interop API
|
||||
|
||||
```sh
|
||||
osr-cad sw --src='./products/asterix-pp/cad/*.+(SLDASM)' --dst='${SRC_DIR}/${SRC_NAME}.+(html)'
|
||||
```
|
||||
|
||||
### Extract all configurations and their custom properties to a JSON file
|
||||
|
||||
**Note** : append the destination path with `-configs.json` ! It accepts only `SLDASM` as source!
|
||||
|
||||
```sh
|
||||
osr-cad sw --src='./products/asterix-pp/cad/*.+(SLDASM)' --dst='${SRC_DIR}/${SRC_NAME}-configs.+(json)'
|
||||
```
|
||||
|
||||
### Convert all assembly configurations to step & HTML
|
||||
|
||||
**Note** : append the destination path with `${CONFIGURATION}` to enumerate through all configurations ! It accepts only `SLDASM` as source!
|
||||
|
||||
```sh
|
||||
osr-cad sw --src='./products/asterix-pp/cad/*.+(SLDASM)' --dst='${SRC_DIR}/${SRC_NAME}-${CONFIGURATION}.+(step|html)'
|
||||
```
|
||||
|
||||
### Export drawio files to png, pdf or jpg
|
||||
|
||||
**Remarks**
|
||||
|
||||
- make sure that draw.io.exe is being found globally (add the path to Draw.io to your Environment path variable! )
|
||||
- Draw.io can be downloaded here [https://github.com/jgraph/drawio-desktop/releases/tag/v14.6.13](https://github.com/jgraph/drawio-desktop/releases/tag/v14.6.13)
|
||||
- to see more options, please run ```draw.io.exe --help```: (forward the arguments using ```--args='-t'```)
|
||||
|
||||
```bash
|
||||
Usage: draw.io [options] [input file/folder]
|
||||
|
||||
Options:
|
||||
-V, --version output the version number
|
||||
-c, --create creates a new empty file if no file is
|
||||
passed
|
||||
-k, --check does not overwrite existing files
|
||||
-x, --export export the input file/folder based on the
|
||||
given options
|
||||
-r, --recursive for a folder input, recursively convert
|
||||
all files in sub-folders also
|
||||
-o, --output <output file/folder> specify the output file/folder. If
|
||||
omitted, the input file name is used for
|
||||
output with the specified format as
|
||||
extension
|
||||
-f, --format <format> if output file name extension is
|
||||
specified, this option is ignored (file
|
||||
type is determined from output extension,
|
||||
possible export formats are pdf, png, jpg,
|
||||
svg, vsdx, and xml) (default: "pdf")
|
||||
-q, --quality <quality> output image quality for JPEG (default:
|
||||
90)
|
||||
-t, --transparent set transparent background for PNG
|
||||
-e, --embed-diagram includes a copy of the diagram (for PNG
|
||||
format only)
|
||||
-b, --border <border> sets the border width around the diagram
|
||||
(default: 0)
|
||||
-s, --scale <scale> scales the diagram size
|
||||
--width <width> fits the generated image/pdf into the
|
||||
specified width, preserves aspect ratio.
|
||||
--height <height> fits the generated image/pdf into the
|
||||
specified height, preserves aspect ratio.
|
||||
--crop crops PDF to diagram size
|
||||
-a, --all-pages export all pages (for PDF format only)
|
||||
-p, --page-index <pageIndex> selects a specific page, if not specified
|
||||
and the format is an image, the first page
|
||||
is selected
|
||||
-g, --page-range <from>..<to> selects a page range (for PDF format only)
|
||||
-u, --uncompressed Uncompressed XML output (for XML format
|
||||
only)
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
```sh
|
||||
osr-cad sw --src='./products/extrusion/**/*.+(drawio)' --dst='${SRC_DIR}/${SRC_NAME}.+(png)'
|
||||
```
|
||||
|
||||
### Create & export BOMs from assembly files
|
||||
|
||||
**Remarks**
|
||||
|
||||
- it's using by default osr-cad/sw/bom-all.sldbomtbt as table template
|
||||
- run osr-cad --help to see the BOM options
|
||||
|
||||
```sh
|
||||
osr-cad sw --src='./products/extrusion/**/*.+(SLDASM)' --dst='${SRC_DIR}/${SRC_NAME}.+(xlsx)'
|
||||
```
|
||||
|
||||
### Pack Assembly (aka 'pack and go')
|
||||
|
||||
```sh
|
||||
osr-cad pack --src=../../ph3/products/products/injection/elena/cad/Global*.SLDASM --dst="../test"
|
||||
```
|
||||
223
packages/cad/docs/Integration.md
Normal file
223
packages/cad/docs/Integration.md
Normal file
@ -0,0 +1,223 @@
|
||||
# Integration
|
||||
|
||||
## Integration: [Alt-Tap Salamand](https://www.altap.cz/) - Custom Menus
|
||||
|
||||
To use OSR-CAD in custom menus, as follows
|
||||
|
||||

|
||||
|
||||
1. install osr-cad via ```npm i -g @plastichub/osr-cad```
|
||||
2. Register a new custom menu (press F9 on any file)
|
||||
|
||||

|
||||
|
||||
**command** : ```osr-cad```
|
||||
|
||||
**Arguments** : ```sw --alt=true --verbose=true --hash=false --debug=true --skip=false --src="$(FullName)" --dst="&{SRC_DIR}/&{SRC_NAME}.+(step)"```
|
||||
|
||||
Here explained,
|
||||
|
||||
```sh
|
||||
|
||||
sw # osr-cad command
|
||||
--alt=true # use alternate tokenizer, '&' instead of '$' to prevent collisions with Alt-Tab's own variable designator
|
||||
--verbose=true # be verbose
|
||||
--hash=false # don't create hash files (for caching)
|
||||
--debug=true # be even more verbose
|
||||
--skip=false # skip already created files
|
||||
--src="$(FullName)" # use Alt-Tab's variable for the current selected file
|
||||
--dst="&{SRC_DIR}/&{SRC_NAME}.+(step)" # the output destination path
|
||||
```
|
||||
|
||||
### Remarks
|
||||
|
||||
- This will convert any Solidwork supported file format to ```step```. For drawings, assemblies and parts, ```jpg```, ```pdf``` and other 2D formats are supported. Conversions will use the options set in your Solidworks settings.
|
||||
- Multiple selections will be excecuted serial
|
||||
|
||||
## Integration: Custom Grunt Task
|
||||
|
||||
```js
|
||||
|
||||
// eg: cad-convert.js
|
||||
|
||||
const fg = require('fast-glob');
|
||||
|
||||
const cad = require('@plastichub/osr-cad/cad/sw-lib');
|
||||
const cadArgsSanitize = require('@plastichub/osr-cad/argv').sanitize;
|
||||
const cadArgsSanitizeSingle = require('@plastichub/osr-cad/argv').sanitizeSingle;
|
||||
const BPromise = require('bluebird');
|
||||
const {
|
||||
option
|
||||
} = require('grunt');
|
||||
|
||||
const path = require('path');
|
||||
const GLOB_MAIN_ASSEMBLY = "cad/*Global*.+(SLDASM)";
|
||||
|
||||
const create_sync_args = (root, product, input_glob, output_glob, options) => {
|
||||
const src = `${root}/${product}/${input_glob}`;
|
||||
const dst = output_glob;
|
||||
return {
|
||||
src,
|
||||
dst,
|
||||
debug: options.debug,
|
||||
args: "",
|
||||
hash: true,
|
||||
verbose: options.verbose,
|
||||
skip: options.skip,
|
||||
cwd: path.resolve(root)
|
||||
}
|
||||
}
|
||||
|
||||
const create_sync_args_single = (root, product, input_glob, output_glob, options) => {
|
||||
const src = `${root}/${product}/${input_glob}`;
|
||||
const dst = path.resolve(`${root}/${product}/${output_glob}`);
|
||||
return {
|
||||
src,
|
||||
dst,
|
||||
debug: options.debug,
|
||||
args: "",
|
||||
hash: true,
|
||||
verbose: options.verbose,
|
||||
skip: options.skip,
|
||||
cwd: path.resolve(root)
|
||||
}
|
||||
}
|
||||
|
||||
const createMeta = (root, product, options, input, output) => {
|
||||
const args = create_sync_args(root, product, GLOB_MAIN_ASSEMBLY, output, options);
|
||||
const syncArgs = cadArgsSanitize({
|
||||
...args,
|
||||
...options
|
||||
});
|
||||
return cad.convert(syncArgs);
|
||||
}
|
||||
const convert = async (items, options, input, output) => {
|
||||
return BPromise.resolve(items).map((target) => {
|
||||
return createMeta(options.cwd || '.', target, options, input, output);
|
||||
}, {
|
||||
concurrency: 1
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const packAssembly = (root, product, options, input, output) => {
|
||||
const args = create_sync_args_single(root, product, GLOB_MAIN_ASSEMBLY, output, options);
|
||||
const syncArgs = cadArgsSanitizeSingle({
|
||||
...args,
|
||||
...options
|
||||
});
|
||||
return cad.pack(syncArgs);
|
||||
}
|
||||
|
||||
const pack = async (items, options, input, output) => {
|
||||
return BPromise.resolve(items).map((target) => {
|
||||
return packAssembly(options.cwd || '.', target, options, input, output);
|
||||
}, {
|
||||
concurrency: 1
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
module.exports = function (grunt) {
|
||||
const log = grunt.verbose.writeln;
|
||||
grunt.registerMultiTask('cad-convert', 'Convert SW files to ... ', function () {
|
||||
const done = this.async();
|
||||
convert(this.data.items, {
|
||||
verbose: grunt.option('verbose') !== undefined ? grunt.option('verbose') : false,
|
||||
skip: grunt.option('skip') !== undefined ? grunt.option('skip') : true,
|
||||
cwd: grunt.option('cwd'),
|
||||
debug: grunt.option('debug') !== undefined ? grunt.option('debug') : false,
|
||||
}, this.data.input || GLOB_MAIN_ASSEMBLY, this.data.output).then(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
grunt.registerMultiTask('cad-pack', 'Pack and go SW assembly files to ... ', function () {
|
||||
const done = this.async();
|
||||
pack(this.data.items, {
|
||||
verbose: grunt.option('verbose') !== undefined ? grunt.option('verbose') : false,
|
||||
skip: grunt.option('skip') !== undefined ? grunt.option('skip') : true,
|
||||
cwd: grunt.option('cwd'),
|
||||
debug: grunt.option('debug') !== undefined ? grunt.option('debug') : false,
|
||||
}, this.data.input || GLOB_MAIN_ASSEMBLY, this.data.output).then(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
Now extend the Grunt configuration for different conversion tasks.
|
||||
|
||||
```js
|
||||
|
||||
'cad-convert': {
|
||||
json: {
|
||||
items: products,
|
||||
output: '${SRC_DIR}/${SRC_NAME}.+(json)'
|
||||
},
|
||||
html: {
|
||||
items: products,
|
||||
output: '${SRC_DIR}/../resources/${SRC_NAME}.+(html)',
|
||||
input: "/**/*Global*.+(SLDASM)"
|
||||
},
|
||||
htmlex: {
|
||||
items: [grunt.option('product')],
|
||||
output: '${SRC_DIR}/../resources/${SRC_NAME}.+(html)',
|
||||
input: "/**/*Global*.+(SLDASM)"
|
||||
},
|
||||
step: {
|
||||
items: products,
|
||||
output: '${SRC_DIR}/${SRC_NAME}.+(step)'
|
||||
},
|
||||
bom: {
|
||||
items: products,
|
||||
output: '${SRC_DIR}/../resources/${SRC_NAME}.+(xlsx)'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Where ```products``` resolves to
|
||||
|
||||
```js
|
||||
const products = [
|
||||
'products/injection/myriad-spring'
|
||||
]
|
||||
```
|
||||
|
||||
This example assumes a folder `cad` in `products/injection/myriad-spring`, with an assembly `Global.SLDASM`.
|
||||
|
||||
To invoke a particular task:
|
||||
|
||||
```sh
|
||||
grunt cad-convert:html
|
||||
```
|
||||
|
||||
Or to bypass the hardcoded 'product' array:
|
||||
|
||||
```sh
|
||||
grunt cad-convert:htmlex --product='products/injection/myriad-spring`
|
||||
```
|
||||
|
||||
## As batch droplet - single file
|
||||
|
||||
1. create a file toHTML.bat with the following content
|
||||
|
||||
```batch
|
||||
@echo off
|
||||
osr-cad sw --verbose=true --hash=false --debug=true --skip=false --src="%~1" --dst="${SRC_DIR}/${SRC_NAME}.+(html)"
|
||||
|
||||
```
|
||||
|
||||
2. drop any SW supported file onto it, to convert it to an eDrawing HTML webview
|
||||
|
||||
## As batch droplet - folders
|
||||
|
||||
1. create a file toHTMLs.bat with the following content
|
||||
|
||||
```batch
|
||||
@echo off
|
||||
osr-cad sw --verbose=true --hash=false --debug=true --skip=false --src="%~1/**/*.+(SLDASM|SLDPRT)" --dst="${SRC_DIR}/${SRC_NAME}.+(html)"
|
||||
```
|
||||
|
||||
2. drop a folder SW supported files onto it, to convert it to an eDrawing HTML webview
|
||||
5
packages/cad/docs/Spec.md
Normal file
5
packages/cad/docs/Spec.md
Normal file
@ -0,0 +1,5 @@
|
||||
## OSR - CAD Policies
|
||||
|
||||
### Assemblies
|
||||
|
||||
- **Valid Formats** : STEP, Solidworks, Parasolid
|
||||
399
packages/cad/docs/assets/config_.reg
Normal file
399
packages/cad/docs/assets/config_.reg
Normal file
@ -0,0 +1,399 @@
|
||||
REGEDIT4
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu]
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\1]
|
||||
"Item Name"="OSR-CAD"
|
||||
"Command"=""
|
||||
"Arguments"=""
|
||||
"Initial Directory"=""
|
||||
"Execute Through Shell"=dword:00000000
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000000
|
||||
"Icon"=""
|
||||
"Type"=dword:00000001
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\10]
|
||||
"Item Name"="CAD -> PDF"
|
||||
"Command"="osr-cad"
|
||||
"Arguments"="sw --alt=true --verbose=true --hash=false --debug=true --skip=false --src=\"$(FullName)\" --dst=\"&{SRC_DIR}/&{SRC_NAME}.+(pdf)\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000001
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\11]
|
||||
"Item Name"="CAD -> JPG"
|
||||
"Command"="osr-cad"
|
||||
"Arguments"="sw --alt=true --verbose=true --hash=false --debug=true --skip=false --src=\"$(FullName)\" --dst=\"&{SRC_DIR}/&{SRC_NAME}.+(jpg)\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000001
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\12]
|
||||
"Item Name"="CAD -> JSON"
|
||||
"Command"="osr-cad"
|
||||
"Arguments"="sw --alt=true --verbose=true --hash=false --debug=true --skip=true --src=\"$(FullName)\" --dst=\"&{SRC_DIR}/&{SRC_NAME}.+(json)\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\13]
|
||||
"Item Name"="CAD -> Parasolid"
|
||||
"Command"="osr-cad"
|
||||
"Arguments"="sw --alt=true --verbose=true --hash=false --debug=true --skip=true --src=\"$(FullName)\" --dst=\"&{SRC_DIR}/&{SRC_NAME}.+(x_t)\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\14]
|
||||
"Item Name"="CAD -> 3MF"
|
||||
"Command"="osr-cad"
|
||||
"Arguments"="sw --alt=true --verbose=true --hash=false --debug=true --skip=true --src=\"$(FullName)\" --dst=\"&{SRC_DIR}/&{SRC_NAME}.+(glb)\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\15]
|
||||
"Item Name"="CAD - > Configs"
|
||||
"Command"="osr-cad"
|
||||
"Arguments"="sw --alt=true --verbose=true --hash=false --debug=true --skip=true --src=\"$(FullName)\" --dst=\"&{SRC_DIR}/&{SRC_NAME}-configs.+(json)\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\16]
|
||||
"Item Name"="CAD - > All Configs"
|
||||
"Command"="osr-cad"
|
||||
"Arguments"="sw --alt=true --verbose=true --hash=false --debug=true --skip=true --src=\"$(FullName)\" --dst=\"&{SRC_DIR}/&{SRC_NAME}-&{CONFIGURATION}.+(step|x_t)\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000001
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\17]
|
||||
"Item Name"="---"
|
||||
"Command"=""
|
||||
"Arguments"=""
|
||||
"Initial Directory"=""
|
||||
"Execute Through Shell"=dword:00000000
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000000
|
||||
"Icon"=""
|
||||
"Type"=dword:00000003
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\18]
|
||||
"Item Name"="(Submenu End)"
|
||||
"Command"=""
|
||||
"Arguments"=""
|
||||
"Initial Directory"=""
|
||||
"Execute Through Shell"=dword:00000000
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000000
|
||||
"Icon"=""
|
||||
"Type"=dword:00000002
|
||||
"Show In Toolbar"=dword:00000000
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\19]
|
||||
"Item Name"="OSR-i18n"
|
||||
"Command"=""
|
||||
"Arguments"=""
|
||||
"Initial Directory"=""
|
||||
"Execute Through Shell"=dword:00000000
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000000
|
||||
"Icon"=""
|
||||
"Type"=dword:00000001
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\2]
|
||||
"Item Name"="---"
|
||||
"Command"=""
|
||||
"Arguments"=""
|
||||
"Initial Directory"=""
|
||||
"Execute Through Shell"=dword:00000000
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000000
|
||||
"Icon"=""
|
||||
"Type"=dword:00000003
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\20]
|
||||
"Item Name"="DE"
|
||||
"Command"="osr-i18n"
|
||||
"Arguments"="translate --alt=true --targetLang=\"DE\" --debug --src=\"$(FullName)\" --dst=\"&{SRC_DIR}/&{SRC_NAME}.&{DST_LANG}.+(md).md\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\21]
|
||||
"Item Name"="(Submenu End)"
|
||||
"Command"=""
|
||||
"Arguments"=""
|
||||
"Initial Directory"=""
|
||||
"Execute Through Shell"=dword:00000000
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000000
|
||||
"Icon"=""
|
||||
"Type"=dword:00000002
|
||||
"Show In Toolbar"=dword:00000000
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\22]
|
||||
"Item Name"="OSR-L"
|
||||
"Command"=""
|
||||
"Arguments"=""
|
||||
"Initial Directory"=""
|
||||
"Execute Through Shell"=dword:00000000
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000000
|
||||
"Icon"=""
|
||||
"Type"=dword:00000001
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\23]
|
||||
"Item Name"="compile"
|
||||
"Command"="osrl"
|
||||
"Arguments"="compile --alt=true --source=\"$(FullName)\" --output=\"&{SRC_DIR}/&{SRC_NAME}.md\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\24]
|
||||
"Item Name"="(Submenu End)"
|
||||
"Command"=""
|
||||
"Arguments"=""
|
||||
"Initial Directory"=""
|
||||
"Execute Through Shell"=dword:00000000
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000000
|
||||
"Icon"=""
|
||||
"Type"=dword:00000002
|
||||
"Show In Toolbar"=dword:00000000
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\25]
|
||||
"Item Name"="OSR-SYNC"
|
||||
"Command"=""
|
||||
"Arguments"=""
|
||||
"Initial Directory"=""
|
||||
"Execute Through Shell"=dword:00000000
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000000
|
||||
"Icon"=""
|
||||
"Type"=dword:00000001
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\26]
|
||||
"Item Name"="OSR-SYNC"
|
||||
"Command"="osr-sync "
|
||||
"Arguments"="sync --alt=true --clean=false --verbose=true --debug=true --source=\"$(FullName)\" --target=\"&{OSR_ROOT}/temp/$(Name)\" --profile=\"&{OSR_ROOT}/osr-commons/profiles/.osr-sync-public.json\" "
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\27]
|
||||
"Item Name"="OSR-SYNC-OTHER-SIDE"
|
||||
"Command"="osr-sync"
|
||||
"Arguments"="sync --alt=true --clean=true --verbose=true --debug=true --source=\"$(FullName)\" --target=\"$(FullPathInactive)/$(Name)\" --profile=\"&{OSR_ROOT}/osr-commons/profiles/.osr-sync-public.json\" "
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\28]
|
||||
"Item Name"="OSR-SYNC-Module"
|
||||
"Command"="osr-sync"
|
||||
"Arguments"="sync --alt=true --clean=true --verbose=true --debug=true --source=\"$(FullName)\" --target=\"$(FullPathInactive)/$(Name)\" --profile=\"&{OSR_ROOT}/osr-commons/profiles/.osr-sync-module.json\" "
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000001
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\29]
|
||||
"Item Name"="(Submenu End)"
|
||||
"Command"=""
|
||||
"Arguments"=""
|
||||
"Initial Directory"=""
|
||||
"Execute Through Shell"=dword:00000000
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000000
|
||||
"Icon"=""
|
||||
"Type"=dword:00000002
|
||||
"Show In Toolbar"=dword:00000000
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\3]
|
||||
"Item Name"="DRAW-IO -> PNG"
|
||||
"Command"="osr-cad"
|
||||
"Arguments"="sw --alt=true --verbose=true --hash=false --debug=true --skip=false --src=\"$(FullName)\" --dst=\"&{SRC_DIR}/&{SRC_NAME}.+(png)\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\30]
|
||||
"Item Name"="OSR-Media"
|
||||
"Command"=""
|
||||
"Arguments"=""
|
||||
"Initial Directory"=""
|
||||
"Execute Through Shell"=dword:00000000
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000000
|
||||
"Icon"=""
|
||||
"Type"=dword:00000001
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\31]
|
||||
"Item Name"="JPG-Resize-Dir-80%"
|
||||
"Command"="osr-media"
|
||||
"Arguments"="resize --minWidth=1900 --width=1980 --alt=true --verbose=true --debug=true --src=\"$(FullName)/**/*.+(&{IMAGES})\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000001
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\32]
|
||||
"Item Name"="WEBP->JPG"
|
||||
"Command"="osr-media"
|
||||
"Arguments"="resize --percent=100 --alt=true --verbose=true --debug=true --src=\"$(FullName)/*.+(webp)\" --dst=\"$(FullName)/*.+(jpg)\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\33]
|
||||
"Item Name"="(Submenu End)"
|
||||
"Command"=""
|
||||
"Arguments"=""
|
||||
"Initial Directory"=""
|
||||
"Execute Through Shell"=dword:00000000
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000000
|
||||
"Icon"=""
|
||||
"Type"=dword:00000002
|
||||
"Show In Toolbar"=dword:00000000
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\4]
|
||||
"Item Name"="DRAW-IO -> PDF"
|
||||
"Command"="osr-cad"
|
||||
"Arguments"="sw --alt=true --verbose=true --hash=false --debug=true --skip=false --src=\"$(FullName)\" --dst=\"&{SRC_DIR}/&{SRC_NAME}.+(pdf)\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000001
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\5]
|
||||
"Item Name"="DRAW-IO -> JPG"
|
||||
"Command"="osr-cad"
|
||||
"Arguments"="sw --alt=true --verbose=true --hash=false --debug=true --skip=false --src=\"$(FullName)\" --dst=\"&{SRC_DIR}/&{SRC_NAME}.+(jpg)\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\6]
|
||||
"Item Name"="DRAW-IO -> SVG"
|
||||
"Command"="osr-cad"
|
||||
"Arguments"="sw --alt=true --verbose=true --hash=false --debug=true --skip=false --src=\"$(FullName)\" --dst=\"&{SRC_DIR}/&{SRC_NAME}.+(svg)\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\7]
|
||||
"Item Name"="---"
|
||||
"Command"=""
|
||||
"Arguments"=""
|
||||
"Initial Directory"=""
|
||||
"Execute Through Shell"=dword:00000000
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000000
|
||||
"Icon"=""
|
||||
"Type"=dword:00000003
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\8]
|
||||
"Item Name"="CAD -> HTML"
|
||||
"Command"="osr-cad"
|
||||
"Arguments"="sw --alt=true --verbose=false --hash=false --debug=false --skip=true --src=\"$(FullName)\" --dst=\"&{SRC_DIR}/&{SRC_NAME}.+(html)\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000000
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
|
||||
[HKEY_CURRENT_USER\Software\Altap\Altap Salamander 4.0\User Menu\9]
|
||||
"Item Name"="CAD -> STEP"
|
||||
"Command"="osr-cad"
|
||||
"Arguments"="sw --alt=true --verbose=true --hash=false --debug=true --skip=false --src=\"$(FullName)\" --dst=\"&{SRC_DIR}/&{SRC_NAME}.+(step)\""
|
||||
"Initial Directory"="$(FullPath)"
|
||||
"Execute Through Shell"=dword:00000001
|
||||
"Close Shell Window"=dword:00000001
|
||||
"Open Shell Window"=dword:00000001
|
||||
"Icon"=""
|
||||
"Type"=dword:00000000
|
||||
"Show In Toolbar"=dword:00000001
|
||||
BIN
packages/cad/docs/assets/integration-as-custom-menu-register.PNG
Normal file
BIN
packages/cad/docs/assets/integration-as-custom-menu-register.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
BIN
packages/cad/docs/assets/integration-as-custom-menu.PNG
Normal file
BIN
packages/cad/docs/assets/integration-as-custom-menu.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
60
packages/cad/package.json
Normal file
60
packages/cad/package.json
Normal file
@ -0,0 +1,60 @@
|
||||
{
|
||||
"name": "@polymech/cad",
|
||||
"version": "0.8.8",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"help": "node build/main.js --help",
|
||||
"build": "tsc -p .",
|
||||
"dev": "tsc -w -p . --declaration",
|
||||
"publish": "npm publish --access public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://git.osr-plastic.org/osr-plastic/cad.git"
|
||||
},
|
||||
"author": "PlasticHub",
|
||||
"keywords": [
|
||||
"SolidWorks",
|
||||
"CAD",
|
||||
"STEP",
|
||||
"3DXML",
|
||||
"3D"
|
||||
],
|
||||
"bin": {
|
||||
"osr-cad": "main.js"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://git.osr-plastic.org/osr-plastic/cad/issues"
|
||||
},
|
||||
"homepage": "https://git.osr-plastic.org/osr-plastic/cad#readme",
|
||||
"dependencies": {
|
||||
"@polymech/cache": "link:..\\cache",
|
||||
"@polymech/commons": "link:..\\commons",
|
||||
"@polymech/core": "link:..\\core",
|
||||
"@polymech/fs": "link:..\\fs",
|
||||
"@types/node": "^20.17.9",
|
||||
"@types/yargs": "^17.0.11",
|
||||
"add": "^2.0.6",
|
||||
"csv-stringify": "^5.6.1",
|
||||
"dxf-parser": "^1.1.2",
|
||||
"errlop": "^2.1.0",
|
||||
"fast-glob": "^3.3.2",
|
||||
"js-yaml": "^4.1.0",
|
||||
"md5": "^2.3.0",
|
||||
"p-map": "^7.0.3",
|
||||
"parse-glob": "^2.0.1",
|
||||
"regexp.escape": "^1.1.0",
|
||||
"tslint": "^5.10.0",
|
||||
"which": "^2.0.2",
|
||||
"yargs": "^17.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.3",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/which": "^1.3.2"
|
||||
}
|
||||
}
|
||||
13
packages/cad/scripts/ExportBOM.sh
Normal file
13
packages/cad/scripts/ExportBOM.sh
Normal file
@ -0,0 +1,13 @@
|
||||
# explicit SW assemblies to HTML via edrawings
|
||||
# node ./main sw \
|
||||
# --skip=false \
|
||||
# --dry=true \
|
||||
# --debug=true \
|
||||
# --verbose=true \
|
||||
# --alt=true \
|
||||
# --src='./tests/drive/*.+(SLDASM)' \
|
||||
# --dst='${SRC_DIR}/${SRC_NAME}.+(html)'
|
||||
|
||||
|
||||
sw/2022/bom.exe "C:\Users\mc007\Desktop\osr\osr-cad\tests\drive\400_Drive.SLDASM" "C:\Users\mc007\Desktop\osr\osr-cad\tests\drive\400_Drive.xlsx"
|
||||
|
||||
13
packages/cad/scripts/ExportHTML.sh
Normal file
13
packages/cad/scripts/ExportHTML.sh
Normal file
@ -0,0 +1,13 @@
|
||||
# explicit SW assemblies to HTML via edrawings
|
||||
# node ./main sw \
|
||||
# --skip=false \
|
||||
# --dry=true \
|
||||
# --debug=true \
|
||||
# --verbose=true \
|
||||
# --alt=true \
|
||||
# --src='./tests/drive/*.+(SLDASM)' \
|
||||
# --dst='${SRC_DIR}/${SRC_NAME}.+(html)'
|
||||
|
||||
|
||||
sw/2022/ExportHTML.exe "C:\Users\mc007\Desktop\osr\osr-cad\tests\drive\400_Drive.SLDASM" "C:\Users\mc007\Desktop\osr\osr-cad\tests\drive\400_Drive.html"
|
||||
|
||||
22
packages/cad/scripts/build/nexe.js
Normal file
22
packages/cad/scripts/build/nexe.js
Normal file
@ -0,0 +1,22 @@
|
||||
const { compile } = require('nexe')
|
||||
|
||||
compile({
|
||||
input: './main.js',
|
||||
build: true, //required to use patches
|
||||
clean:false,
|
||||
output:'./dist/win32/osr-cad.exe',
|
||||
verbose:true,
|
||||
fakeArgv: false,
|
||||
temp:'./.nexe',
|
||||
_patches: [
|
||||
async (compiler, next) => {
|
||||
await compiler.setFileContentsAsync(
|
||||
'lib/new-native-module.js',
|
||||
'module.exports = 42'
|
||||
)
|
||||
return next()
|
||||
}
|
||||
]
|
||||
}).then(() => {
|
||||
console.log('success')
|
||||
})
|
||||
1
packages/cad/scripts/build/win.sh
Normal file
1
packages/cad/scripts/build/win.sh
Normal file
@ -0,0 +1 @@
|
||||
npx nexe .\main.js osr-cad.exe --build --verbose
|
||||
20
packages/cad/scripts/single-asm-to-bom.sh
Normal file
20
packages/cad/scripts/single-asm-to-bom.sh
Normal file
@ -0,0 +1,20 @@
|
||||
# explicit SW assemblies to HTML via edrawings
|
||||
# node ./main sw \
|
||||
# --skip=false \
|
||||
# --dry=true \
|
||||
# --debug=true \
|
||||
# --verbose=true \
|
||||
# --alt=true \
|
||||
# --src='./tests/drive/*.+(SLDASM)' \
|
||||
# --dst='${SRC_DIR}/${SRC_NAME}.+(html)'
|
||||
|
||||
|
||||
node ./main sw \
|
||||
--skip=false \
|
||||
--dry=false \
|
||||
--debug=true \
|
||||
--verbose=true \
|
||||
--alt=true \
|
||||
--src='./tests/drive/*.+(SLDASM)' \
|
||||
--dst='&{SRC_DIR}/&{SRC_NAME}.+(xlsx)'
|
||||
|
||||
19
packages/cad/scripts/single-asm-to-html.sh
Normal file
19
packages/cad/scripts/single-asm-to-html.sh
Normal file
@ -0,0 +1,19 @@
|
||||
# explicit SW assemblies to HTML via edrawings
|
||||
# node ./main sw \
|
||||
# --skip=false \
|
||||
# --dry=true \
|
||||
# --debug=true \
|
||||
# --verbose=true \
|
||||
# --alt=true \
|
||||
# --src='./tests/drive/*.+(SLDASM)' \
|
||||
# --dst='${SRC_DIR}/${SRC_NAME}.+(html)'
|
||||
|
||||
|
||||
node ./main sw \
|
||||
--skip=true \
|
||||
--dry=false \
|
||||
--debug=true \
|
||||
--verbose=true \
|
||||
--alt=true \
|
||||
--src='./tests/drive/*.+(SLDASM)' \
|
||||
--dst='&{SRC_DIR}/&{SRC_NAME}.+(html)'
|
||||
4
packages/cad/scripts/tests.sh
Normal file
4
packages/cad/scripts/tests.sh
Normal file
@ -0,0 +1,4 @@
|
||||
## Draw.io to png
|
||||
node main.js sw --alt=true --verbose=true --debug=true --skip=false --src="C:\Users\mc007\Desktop\osr\system\_pages\packages.drawio" --dst="&{SRC_DIR}/&{SRC_NAME}.+(png)"
|
||||
node main.js sw --alt=true --verbose=true --debug=true --skip=false --src="C:\Users\mc007\Desktop\osr\system\_pages\packages.drawio" --dst="&{SRC_DIR}/&{SRC_NAME}.+(jpg)"
|
||||
node main.js sw --alt=true --verbose=true --debug=true --skip=false --src="C:\Users\mc007\Desktop\osr\system\_pages\packages.drawio" --dst="&{SRC_DIR}/&{SRC_NAME}.+(pdf)"
|
||||
0
packages/cad/src/.gitignore
vendored
Normal file
0
packages/cad/src/.gitignore
vendored
Normal file
13
packages/cad/src/_cli.ts
Normal file
13
packages/cad/src/_cli.ts
Normal file
@ -0,0 +1,13 @@
|
||||
// tweaks and handlers
|
||||
export const defaults = () => {
|
||||
// default command
|
||||
const DefaultCommand = 'summary';
|
||||
if (process.argv.length === 2) {
|
||||
process.argv.push(DefaultCommand);
|
||||
}
|
||||
|
||||
// currently no default handler, display only :
|
||||
process.on('unhandledRejection', (reason: string) => {
|
||||
console.error('Unhandled rejection, reason: ', reason);
|
||||
});
|
||||
};
|
||||
1
packages/cad/src/cad/index.ts
Normal file
1
packages/cad/src/cad/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { convert, pack } from './sw-lib'
|
||||
384
packages/cad/src/cad/sw-convert.ts
Normal file
384
packages/cad/src/cad/sw-convert.ts
Normal file
@ -0,0 +1,384 @@
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import * as pMap from 'p-map'
|
||||
import { sync as which } from 'which'
|
||||
import { resolve, OSR_CACHE } from '@plastichub/osr-commons'
|
||||
import { equalFiles, swProcMessage } from './sw-util'
|
||||
import { reportCSV } from '../report'
|
||||
import { logger, substitute } from '..'
|
||||
import { removeEmpty } from '../lib/'
|
||||
import { SolidworkOptions } from '../types'
|
||||
import { Helper } from '../lib/process/index'
|
||||
|
||||
import { sync as exists } from "@plastichub/fs/exists"
|
||||
import { sync as read } from "@plastichub/fs/read"
|
||||
import { sync as write } from "@plastichub/fs/write"
|
||||
import { sync as dir } from "@plastichub/fs/dir"
|
||||
import { sync as rm } from "@plastichub/fs/remove"
|
||||
import { clone } from "@plastichub/core/objects"
|
||||
|
||||
import { swRayTraceRenderQuality_e, IAssembly, IAssemblyData } from './sw-types'
|
||||
|
||||
import { get_cached, get_path_cached, get_cache_key, set_cached } from '@plastichub/osr-cache/lib'
|
||||
|
||||
import {
|
||||
BUF_SIZE_CMP,
|
||||
MODULE_NAME,
|
||||
MSG_FAILED_TO_LOAD
|
||||
} from '../constants'
|
||||
|
||||
import { closeAppByName, fileAsBuffer, getSWBin, removeEmptyValues } from './sw-util'
|
||||
|
||||
export const convertFile = async (
|
||||
src,
|
||||
target,
|
||||
view: string,
|
||||
onNode: (data) => void = () => { },
|
||||
options: SolidworkOptions,
|
||||
configuration: string) => {
|
||||
configuration = options.configuration || configuration
|
||||
options.close && closeAppByName('SLDWORKS')
|
||||
const osr_cache = OSR_CACHE()
|
||||
let cache_key_obj: any = {
|
||||
sw: options.sw,
|
||||
src,
|
||||
target,
|
||||
configuration
|
||||
}
|
||||
if (target.endsWith('.jpg')) {
|
||||
cache_key_obj =
|
||||
{
|
||||
...cache_key_obj,
|
||||
quality: options.quality,
|
||||
width: options.width,
|
||||
height: options.height,
|
||||
renderer: options.renderer
|
||||
}
|
||||
}
|
||||
if (target.endsWith('.xlsx')) {
|
||||
cache_key_obj = {
|
||||
...cache_key_obj,
|
||||
"bom-config": options['bom-config'],
|
||||
"bom-detail": options['bom-detail'],
|
||||
"bom-template": options['bom-template'],
|
||||
"bom-type": options['bom-type'],
|
||||
"bom-images": options['bom-images'],
|
||||
}
|
||||
}
|
||||
const ca_options = JSON.parse(JSON.stringify(removeEmpty(cache_key_obj)))
|
||||
let cached = await get_cached(src, ca_options, MODULE_NAME)
|
||||
const cachedPath = await get_path_cached(src, ca_options, MODULE_NAME)
|
||||
if (!exists(target)) {
|
||||
cached = null;
|
||||
}
|
||||
if (osr_cache && cached && cachedPath && options.cache == true) {
|
||||
if (!exists(target) || !equalFiles(target, cachedPath)) {
|
||||
write(target, Buffer.from(cached))
|
||||
}
|
||||
logger.debug(`[${MODULE_NAME}] Skipping conversion of ${src} to ${target}`)
|
||||
await onNode({ src, target, options })
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
const parts = path.parse(target)
|
||||
const source_parts = path.parse(src)
|
||||
let exe = '' + options.script
|
||||
let cwd = getSWBin(options.sw)
|
||||
let _target = '' + target
|
||||
let onPost = null
|
||||
|
||||
// SW Photoview wont render correctly in hidden mode
|
||||
if (parts.ext === '.jpg' && source_parts.ext.toLowerCase() === '.sldasm' && options.renderer.toLowerCase() === ' ') {
|
||||
logger.debug(`[${MODULE_NAME}] Converting ${src} to ${target} : - Photoview: - ` + options.hidden)
|
||||
options.hidden = "false"
|
||||
}
|
||||
let args = [
|
||||
`--source="${src}"`,
|
||||
`--target="${target}"`,
|
||||
`--configuration="${configuration}"`,
|
||||
`--view="*${view}"`,
|
||||
`--hidden=` + options.hidden || "true",
|
||||
`--width=` + options.width,
|
||||
`--height=` + options.height,
|
||||
`--swv=` + options.swv,
|
||||
`--renderer=` + options.renderer.toLowerCase() || "solidworks",
|
||||
`--quality=${options.quality || swRayTraceRenderQuality_e.swRenderQuality_Good}`
|
||||
]
|
||||
|
||||
if (options.save) args.push(`--save`)
|
||||
if (options.pack) args.push(`--pack`)
|
||||
if (options.rebuild) args.push(`--rebuild`)
|
||||
if (options.light) args.push(`--light`)
|
||||
if (options.write) args.push(`--write`)
|
||||
|
||||
if (parts.ext === '.json' && source_parts.ext.toLowerCase() === '.sldasm') {
|
||||
exe = 'model-reader.exe'
|
||||
args = [
|
||||
`--source="${path.resolve(src)}"`,
|
||||
`--target="${_target}"`
|
||||
]
|
||||
onPost = () => {
|
||||
try {
|
||||
let props = read(_target, 'json') as any[];
|
||||
if (!props) {
|
||||
logger.error('Error reading model file ', src)
|
||||
return false
|
||||
}
|
||||
props = props.map(removeEmpty)
|
||||
write(_target, props)
|
||||
return true
|
||||
} catch (e) {
|
||||
logger.error(`Error executing model-reader::onPost for ${src} to ${_target}`)
|
||||
write(_target, {})
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parts.base.endsWith('-configs.json') && source_parts.ext.toLowerCase() === '.sldasm') {
|
||||
exe = 'getconfigs.exe'
|
||||
args = [
|
||||
`--source="${path.resolve(src)}"`,
|
||||
`--target="${path.resolve(_target)}"`
|
||||
]
|
||||
onPost = () => {
|
||||
try {
|
||||
let props = read(_target, 'json') as any[];
|
||||
if (!props) {
|
||||
logger.error('Error reading configurations file ', src)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} catch (e) {
|
||||
logger.error(`Error executing get::onPost for ${src} to ${_target}`)
|
||||
write(_target, {})
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parts.ext === '.html') {
|
||||
exe = 'ExportHTML.exe'
|
||||
if (!configuration || configuration === 'Default') {
|
||||
args = [
|
||||
`"${src}"`,
|
||||
`"${target}"`,
|
||||
]
|
||||
} else if (configuration) {
|
||||
//EDrawings Control doesnt support configurations directly, we need a configuration specific edrawings file exported instead
|
||||
const eDrawingsFile = src.toLowerCase().replace('.sldasm', `-${configuration}.EASM`)
|
||||
if (!exists(eDrawingsFile)) {
|
||||
logger.error(`Configuration specific edrawing file ${eDrawingsFile} doesnt exists`)
|
||||
return Promise.resolve()
|
||||
}
|
||||
args = [
|
||||
`"${eDrawingsFile}"`,
|
||||
`"${target}"`,
|
||||
`${configuration}`
|
||||
]
|
||||
}
|
||||
}
|
||||
if (parts.ext === '.xlsx') {
|
||||
exe = 'bom.exe';
|
||||
args = [
|
||||
`"${src}"`,
|
||||
`"${target}"`,
|
||||
`--configuration ${options['bom-config']}`,
|
||||
`--type ${options['bom-type']}`,
|
||||
`--detail ${options['bom-detail']}`
|
||||
]
|
||||
|
||||
options['bom-images'] && args.push('--images')
|
||||
options['bom-template'] && args.push(`--template ${options['bom-template']}`)
|
||||
|
||||
if (!options.cache && exists(target)) {
|
||||
rm(target);
|
||||
}
|
||||
}
|
||||
if (source_parts.ext === '.drawio') {
|
||||
exe = 'draw.io.exe';
|
||||
try {
|
||||
cwd = path.parse(which(exe)).dir;
|
||||
} catch (e) {
|
||||
logger.error(`Cant find ${exe}`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
args = [
|
||||
`"${src}"`,
|
||||
'-x',
|
||||
`-f ${parts.ext.replace('.', '')}`,
|
||||
`${options.args}`
|
||||
]
|
||||
}
|
||||
const bin = path.resolve(`${cwd}/${exe}`)
|
||||
if (!exists(bin)) {
|
||||
logger.error(`${bin} doesnt exists in ${cwd}`)
|
||||
logger.error('__dirname:' + __dirname)
|
||||
logger.error('options.sw ' + options.sw)
|
||||
return
|
||||
}
|
||||
const ret = await Helper.run(cwd, exe, args, options.debug)
|
||||
ret.messages = [...new Set(ret.messages)]
|
||||
const failed = !!ret.messages.find((m: string) => m.includes(MSG_FAILED_TO_LOAD))
|
||||
ret.messages = ret.messages.map((m: string) => swProcMessage(m)).filter(x => x != null).map(x => x.message)
|
||||
const info = {
|
||||
...ret,
|
||||
src,
|
||||
target,
|
||||
failed: failed,
|
||||
options
|
||||
}
|
||||
|
||||
await onNode(info)
|
||||
onPost && onPost()
|
||||
if (info.failed) {
|
||||
rm(_target)
|
||||
return ret
|
||||
}
|
||||
osr_cache && options.cache == true && await set_cached(src, ca_options, MODULE_NAME, fileAsBuffer(_target))
|
||||
options.close && closeAppByName('SLDWORKS')
|
||||
return ret
|
||||
}
|
||||
export async function convertFiles(file, targets: string[], view, onNode: (data: any) => void = () => { }, options: SolidworkOptions) {
|
||||
if (options.dry) {
|
||||
logger.info(`Dry run convert ${file} to `, targets.map((t)=>{`\n\t${t}`}).join(',\n'))
|
||||
return Promise.resolve()
|
||||
}
|
||||
return pMap(targets, (target: any) => {
|
||||
return convertFile(file, target.target, view, onNode, options, target.configuration);
|
||||
}, { concurrency: 1 })
|
||||
}
|
||||
export const report = (data, dst: string) => {
|
||||
|
||||
let report: any = null;
|
||||
if (dst.endsWith('.md')) {
|
||||
//report = reportMarkdown(data)
|
||||
}
|
||||
|
||||
if (dst.endsWith('.csv')) {
|
||||
report = reportCSV(data)
|
||||
}
|
||||
|
||||
logger.info(`Write report to ${dst}`)
|
||||
report = write(dst, data)
|
||||
|
||||
return report;
|
||||
}
|
||||
export const targets = (f: string, options: SolidworkOptions) => {
|
||||
const srcParts = path.parse(f)
|
||||
const variables = clone(options.variables)
|
||||
const targets = []
|
||||
|
||||
let configurations: any = { "Default": null }
|
||||
if (options.configuration && options.configuration !== 'Default') {
|
||||
configurations[options.configuration] = null
|
||||
delete configurations["Default"]
|
||||
}
|
||||
if (options.dstInfo.PATH.includes('{CONFIGURATION}') &&
|
||||
srcParts.ext.toLowerCase() === '.sldasm') {
|
||||
const configurationsFile = `${srcParts.dir}/${srcParts.name}-configs.json`
|
||||
if (exists(configurationsFile)) {
|
||||
try {
|
||||
configurations = read(configurationsFile, 'json')
|
||||
} catch (error) {
|
||||
logger.error(`Error reading configurations file ${configurationsFile}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const conf in configurations) {
|
||||
if (options.dstInfo.IS_GLOB) {
|
||||
options.dstInfo.GLOB_EXTENSIONS.forEach((e) => {
|
||||
variables.SRC_NAME = srcParts.name
|
||||
variables.SRC_DIR = srcParts.dir
|
||||
variables.CONFIGURATION = conf
|
||||
let targetPath = substitute(options.alt, options.variables.DST_PATH, variables)
|
||||
targetPath = path.resolve(targetPath.replace(options.variables.DST_FILE_EXT, '') + e)
|
||||
const parts = path.parse(targetPath)
|
||||
if (srcParts.ext === parts.ext) {
|
||||
return
|
||||
}
|
||||
if (!exists(parts.dir)) {
|
||||
try {
|
||||
dir(parts.dir)
|
||||
} catch (e) {
|
||||
if (options.debug) {
|
||||
logger.error(`Error creating target path ${parts.dir} for ${targetPath}`);
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
targets.push({
|
||||
target: targetPath,
|
||||
configuration: conf
|
||||
})
|
||||
})
|
||||
} else {
|
||||
variables.SRC_NAME = srcParts.name
|
||||
variables.SRC_DIR = srcParts.dir
|
||||
variables.CONFIGURATION = conf
|
||||
let targetPath = substitute(options.alt, options.variables.DST_PATH, variables)
|
||||
if (!exists(targetPath)) {
|
||||
try {
|
||||
dir(targetPath)
|
||||
} catch (e) {
|
||||
if (options.debug) {
|
||||
logger.error(`Error creating target path ${targetPath}`)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
targets.push({
|
||||
target: targetPath,
|
||||
configuration: conf
|
||||
})
|
||||
}
|
||||
}
|
||||
return targets
|
||||
}
|
||||
export async function convert(options: SolidworkOptions) {
|
||||
logger.setSettings({ minLevel: options.logLevel as any || 'warn' })
|
||||
let reports = []
|
||||
const onNode = options.onNode || ((data) => reports.push(data))
|
||||
if (options.srcInfo.FILES.length === 0) {
|
||||
logger.warn(`No files found to convert : `, options.src)
|
||||
return
|
||||
}
|
||||
//skip orphan / temporary files
|
||||
options.srcInfo.FILES = options.srcInfo.FILES.filter((f) => {
|
||||
return f.includes('~$') === false
|
||||
})
|
||||
|
||||
const ret = await pMap(options.srcInfo.FILES, async (f) => {
|
||||
const outputs = targets(f, options)
|
||||
logger.info(`Convert ${f} to ${outputs.map(t => t.target).join(',')}`)
|
||||
return convertFiles(f, outputs, options.view, onNode, options)
|
||||
}, { concurrency: 1 })
|
||||
|
||||
if (options.report) {
|
||||
const reportOutFile: string = path.resolve(resolve(options.report, false, {
|
||||
dst: options.srcInfo.DIR,
|
||||
...options.variables,
|
||||
CONFIGURATION: options.configuration || ''
|
||||
}))
|
||||
logger.debug(`Write report to ${reportOutFile}`)
|
||||
report(reports, reportOutFile)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
/*
|
||||
const on3DHTML = (src, dst, options: SolidworkOptions) => {
|
||||
const web_root = path.resolve(__dirname + '/../../web/xeo');
|
||||
const config = JSON.parse(read(path.resolve(__dirname + '/../../config.json')) as any);
|
||||
const templatePath = path.resolve(`${web_root}/template.html`);
|
||||
const template = read(templatePath, 'string') as string;
|
||||
|
||||
const srcParts = path.parse(src);
|
||||
const variables = {
|
||||
...config.variables,
|
||||
SRC_PATH_WEB: './' + srcParts.name + '_3D.html',
|
||||
MODEL_SRC: './' + srcParts.name + '.3dxml',
|
||||
};
|
||||
|
||||
const content = substitute(false, template, variables);
|
||||
write(dst, content);
|
||||
}
|
||||
*/
|
||||
23
packages/cad/src/cad/sw-lib.ts
Normal file
23
packages/cad/src/cad/sw-lib.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import * as pMap from 'p-map'
|
||||
import { sync as which } from 'which'
|
||||
import { execSync } from 'child_process'
|
||||
|
||||
import { reportCSV } from '../report'
|
||||
import { logger, substitute } from '..'
|
||||
import { removeEmpty } from '../lib/'
|
||||
import { SolidworkOptions } from '../types'
|
||||
import { Helper } from '../lib/process/index'
|
||||
|
||||
import { sync as exists } from "@plastichub/fs/exists"
|
||||
import { sync as read } from "@plastichub/fs/read"
|
||||
import { sync as write } from "@plastichub/fs/write"
|
||||
import { sync as dir } from "@plastichub/fs/dir"
|
||||
import { sync as rm } from "@plastichub/fs/remove"
|
||||
import { clone } from "@plastichub/core/objects"
|
||||
|
||||
export * from './sw-convert'
|
||||
export * from './sw-util'
|
||||
export * from './sw-pack'
|
||||
|
||||
62
packages/cad/src/cad/sw-pack.ts
Normal file
62
packages/cad/src/cad/sw-pack.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import * as path from 'path'
|
||||
import * as pMap from 'p-map'
|
||||
|
||||
import { logger } from '..'
|
||||
import { SolidworkOptions } from '../types'
|
||||
import { Helper } from '../lib/process/index'
|
||||
|
||||
import { sync as exists } from "@plastichub/fs/exists"
|
||||
|
||||
|
||||
import { getSWBin } from './sw-util'
|
||||
|
||||
export async function packFile(file, onNode: (data: any) => void = () => { }, options: SolidworkOptions) {
|
||||
if (options.dry) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const target = options.dst;
|
||||
if (options.cache && exists(target)) {
|
||||
onNode({
|
||||
src: file,
|
||||
target
|
||||
});
|
||||
return Promise.resolve();
|
||||
}
|
||||
let exe = '' + options.script;
|
||||
let args = [
|
||||
`"${file}"`,
|
||||
`"${target}"`
|
||||
]
|
||||
|
||||
|
||||
const cwd = getSWBin(options.sw);
|
||||
const bin = path.resolve(`${cwd}/${exe}`);
|
||||
if (!exists(bin)) {
|
||||
logger.error(`${bin} doesnt exists in ${cwd}`)
|
||||
logger.error('__dirname:' + __dirname)
|
||||
logger.error('options.sw ' + options.sw)
|
||||
return
|
||||
}
|
||||
|
||||
options.debug && logger.debug(`Running ${cwd}/${exe} with`, args)
|
||||
const promise = Helper.run(cwd, exe, args, options.debug)
|
||||
promise.then((d) => {
|
||||
onNode({
|
||||
...d,
|
||||
src: file,
|
||||
target
|
||||
})
|
||||
})
|
||||
return promise
|
||||
}
|
||||
|
||||
export async function pack(options: SolidworkOptions) {
|
||||
let reports = []
|
||||
const onNode = (data) => { reports.push(data) }
|
||||
options.verbose && logger.info(`Pack ${options.srcInfo.FILES.length} files `)
|
||||
const ret = await pMap(options.srcInfo.FILES, async (f) => {
|
||||
logger.debug(`Convert ${f} to `, options.dst)
|
||||
return packFile(f, onNode, options)
|
||||
}, { concurrency: 1 })
|
||||
return ret
|
||||
}
|
||||
252
packages/cad/src/cad/sw-types.ts
Normal file
252
packages/cad/src/cad/sw-types.ts
Normal file
@ -0,0 +1,252 @@
|
||||
export interface IComponent {
|
||||
Name: string;
|
||||
Path: string;
|
||||
IsSuppressed: boolean;
|
||||
}
|
||||
|
||||
export interface IMass {
|
||||
Mass: number;
|
||||
Density: number;
|
||||
Volume: number;
|
||||
SurfaceArea: number;
|
||||
CenterOfMassX: number;
|
||||
CenterOfMassY: number;
|
||||
CenterOfMassZ: number;
|
||||
}
|
||||
|
||||
export interface IBox {
|
||||
MinX: number;
|
||||
MinY: number;
|
||||
MinZ: number;
|
||||
MaxX: number;
|
||||
MaxY: number;
|
||||
MaxZ: number;
|
||||
}
|
||||
|
||||
export interface IMaterial {
|
||||
Material: string;
|
||||
"Materials": string;
|
||||
}
|
||||
|
||||
export interface IProperties {
|
||||
[key: string]: object;
|
||||
}
|
||||
|
||||
export interface IAssembly {
|
||||
Components: IComponent[];
|
||||
}
|
||||
|
||||
|
||||
export interface ITreeNode {
|
||||
Name: string
|
||||
Children: Node[]
|
||||
Path: string
|
||||
Parent: string | null
|
||||
Properties: IProperties
|
||||
Equations: { [key: string]: number | string }
|
||||
Mass: IMass
|
||||
Box: IBox
|
||||
Material: { [key: string]: string }
|
||||
States: { [key: string]: object }
|
||||
LaserParts: any
|
||||
activeConfiguration: any
|
||||
}
|
||||
export interface Configuration {
|
||||
"Total Bounding Box Length"?: string
|
||||
"Total Bounding Box Width"?: string
|
||||
"Total Bounding Box Thickness"?: string
|
||||
"Total Bounding Box Volume"?: string
|
||||
"Weight"?: string
|
||||
"Cost - Total Cost"?: string
|
||||
"IsLaser?": string
|
||||
"Hide"?: string
|
||||
"Catalog"?: string
|
||||
"Configurations"?: string
|
||||
}
|
||||
|
||||
export interface Configurations {
|
||||
[key:string]: Configuration
|
||||
}
|
||||
|
||||
export interface IAssemblyData {
|
||||
assembly: IAssembly
|
||||
root: ITreeNode
|
||||
Configurations: Configurations
|
||||
}
|
||||
|
||||
export enum swRayTraceRenderImageFormat {
|
||||
swImageFormat_FlexiblePrecision,
|
||||
swImageFormat_Targa,
|
||||
swImageFormat_WindowsBmp,
|
||||
swImageFormat_HDR,
|
||||
swImageFormat_JPEG2000,
|
||||
swImageFormat_JPEG2000_16bit,
|
||||
swImageFormat_JPEG2000_16bit_Lossless,
|
||||
swImageFormat_JPEG,
|
||||
swImageFormat_PNG,
|
||||
swImageFormat_PNG_16bit,
|
||||
swImageFormat_SGI_RGB,
|
||||
swImageFormat_TIF,
|
||||
swImageFormat_TIF_16bit,
|
||||
swImageFormat_TIF_16bit_uncompr,
|
||||
swImageFormat_OpenEXR,
|
||||
swImageFormat_OpenEXR_32bit,
|
||||
swImageFormat_OpenEXR_TILED16bit,
|
||||
swImageFormat_OpenEXR_TILED32bit
|
||||
}
|
||||
|
||||
export enum swRayTraceRenderQuality_e {
|
||||
swRenderQuality_Good,
|
||||
swRenderQuality_Better,
|
||||
swRenderQuality_Best,
|
||||
swRenderQuality_Maximum
|
||||
}
|
||||
|
||||
export enum ImageAspectRatio {
|
||||
AspectRatio_1_1 = "1:1",
|
||||
AspectRatio_4_3 = "4:3",
|
||||
AspectRatio_16_9 = "16:9",
|
||||
AspectRatio_21_9 = "21:9",
|
||||
AspectRatio_2_3 = "2:3",
|
||||
AspectRatio_3_2 = "3:2",
|
||||
AspectRatio_5_4 = "5:4",
|
||||
AspectRatio_3_4 = "3:4",
|
||||
AspectRatio_9_16 = "9:16",
|
||||
AspectRatio_10_16 = "10:16",
|
||||
AspectRatio_16_10 = "16:10",
|
||||
AspectRatio_16_15 = "16:15",
|
||||
AspectRatio_18_9 = "18:9",
|
||||
AspectRatio_32_9 = "32:9",
|
||||
AspectRatio_48_9 = "48:9",
|
||||
}
|
||||
|
||||
export enum ImageResolution {
|
||||
Resolution_640x480 = "640x480",
|
||||
Resolution_800x600 = "800x600",
|
||||
Resolution_1024x768 = "1024x768",
|
||||
Resolution_1280x720 = "1280x720",
|
||||
Resolution_1280x800 = "1280x800",
|
||||
Resolution_1280x1024 = "1280x1024",
|
||||
Resolution_1366x768 = "1366x768",
|
||||
Resolution_1440x900 = "1440x900",
|
||||
Resolution_1600x900 = "1600x900",
|
||||
Resolution_1680x1050 = "1680x1050",
|
||||
Resolution_1920x1080 = "1920x1080",
|
||||
Resolution_1920x1200 = "1920x1200",
|
||||
Resolution_2560x1440 = "2560x1440",
|
||||
Resolution_2560x1600 = "2560x1600",
|
||||
Resolution_3840x2160 = "3840x2160",
|
||||
Resolution_4096x2160 = "4096x2160",
|
||||
Resolution_5120x2880 = "5120x2880",
|
||||
Resolution_7680x4320 = "7680x4320",
|
||||
}
|
||||
|
||||
export interface IRayTraceRendererOptions {
|
||||
imageWidth: number;
|
||||
imageHeight: number;
|
||||
imageFormat: number;
|
||||
previewRenderQuality: number;
|
||||
finalRenderQuality: number;
|
||||
bloomEnabled: boolean;
|
||||
bloomThreshold: number;
|
||||
bloomRadius: number;
|
||||
contourEnabled: boolean;
|
||||
shadedContour: boolean;
|
||||
contourLineThickness: number;
|
||||
contourLineColor: number;
|
||||
useSolidWorksViewAspectRatio: boolean;
|
||||
defaultImagePath: string;
|
||||
useSceneBackgroundImageAspectRatio: boolean;
|
||||
outputAmbientOcclusion: boolean;
|
||||
directCaustics: boolean;
|
||||
causticQuality: number;
|
||||
gamma: number;
|
||||
numberOfReflections: number;
|
||||
numberOfRefractions: number;
|
||||
networkRendering: boolean;
|
||||
clientWorkload: number;
|
||||
sendDataForNetworkJob: boolean;
|
||||
networkSharedDirectory: string;
|
||||
causticAmount: number;
|
||||
customRenderSettings: boolean;
|
||||
contourCartoonRenderingEnabled: boolean;
|
||||
hasCartoonEdges: boolean;
|
||||
hasCartoonShading: boolean;
|
||||
includeAnnotationsInRendering: boolean;
|
||||
renderType: number;
|
||||
renderAnnotationsToSeparateImage: boolean;
|
||||
alphaOutput: boolean;
|
||||
offloadedRendering: boolean;
|
||||
}
|
||||
function createRendererOptions(options?: Partial<IRayTraceRendererOptions>): IRayTraceRendererOptions {
|
||||
const defaults: IRayTraceRendererOptions = {
|
||||
imageWidth: 800,
|
||||
imageHeight: 600,
|
||||
imageFormat: 0,
|
||||
previewRenderQuality: 50,
|
||||
finalRenderQuality: 100,
|
||||
bloomEnabled: true,
|
||||
bloomThreshold: 0.5,
|
||||
bloomRadius: 10,
|
||||
contourEnabled: false,
|
||||
shadedContour: false,
|
||||
contourLineThickness: 1,
|
||||
contourLineColor: 0,
|
||||
useSolidWorksViewAspectRatio: false,
|
||||
defaultImagePath: '',
|
||||
useSceneBackgroundImageAspectRatio: false,
|
||||
outputAmbientOcclusion: false,
|
||||
directCaustics: false,
|
||||
causticQuality: 50,
|
||||
gamma: 2.2,
|
||||
numberOfReflections: 2,
|
||||
numberOfRefractions: 2,
|
||||
networkRendering: false,
|
||||
clientWorkload: 0,
|
||||
sendDataForNetworkJob: false,
|
||||
networkSharedDirectory: '',
|
||||
causticAmount: 0.5,
|
||||
customRenderSettings: false,
|
||||
contourCartoonRenderingEnabled: false,
|
||||
hasCartoonEdges: false,
|
||||
hasCartoonShading: false,
|
||||
includeAnnotationsInRendering: false,
|
||||
renderType: 0,
|
||||
renderAnnotationsToSeparateImage: false,
|
||||
alphaOutput: false,
|
||||
offloadedRendering: false,
|
||||
};
|
||||
|
||||
return { ...defaults, ...options };
|
||||
}
|
||||
|
||||
export enum EDocumentState {
|
||||
//
|
||||
// Summary:
|
||||
// Default state of the document
|
||||
Default = 0,
|
||||
//
|
||||
// Summary:
|
||||
// Checks if document is hidden
|
||||
Hidden = 1,
|
||||
//
|
||||
// Summary:
|
||||
// Opens document in read-only mode
|
||||
ReadOnly = 2,
|
||||
//
|
||||
// Summary:
|
||||
// Opens document in view only mode
|
||||
ViewOnly = 4,
|
||||
//
|
||||
// Summary:
|
||||
// Opens document without displaying any popup messages
|
||||
Silent = 8,
|
||||
//
|
||||
// Summary:
|
||||
// Opens document in the rapid mode
|
||||
//
|
||||
// Remarks:
|
||||
// This mode significantly improves the performance of opening but certain functionality
|
||||
// and API migth not be available
|
||||
Rapid = 0x10
|
||||
}
|
||||
87
packages/cad/src/cad/sw-util.ts
Normal file
87
packages/cad/src/cad/sw-util.ts
Normal file
@ -0,0 +1,87 @@
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import { execSync } from 'child_process'
|
||||
import { sync as exists } from "@plastichub/fs/exists"
|
||||
import { sync as read } from "@plastichub/fs/read"
|
||||
|
||||
import { BUF_SIZE_CMP } from '../constants'
|
||||
|
||||
export const swProcMessage = (log: string):{ logLevel: string, message: string } | null => {
|
||||
const regex = /<<(\w+)::(.*?)>>/
|
||||
const match = log.match(regex)
|
||||
if (match) {
|
||||
return {
|
||||
logLevel: match[1],
|
||||
message: match[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
export const fileAsBuffer = (path: string) => read(path, 'buffer') as Buffer || Buffer.from("-")
|
||||
|
||||
export const getSWBin = (argv: string) => {
|
||||
const swVersion = parseInt(argv)
|
||||
if (swVersion) {
|
||||
return path.resolve(__dirname + `/../sw/${swVersion}`)
|
||||
} else {
|
||||
return path.resolve(argv)
|
||||
}
|
||||
}
|
||||
|
||||
export function closeAppByName(appName: string): void {
|
||||
try {
|
||||
const command = `tasklist /FI "IMAGENAME eq ${appName}.exe" /NH`;
|
||||
const output = execSync(command).toString();
|
||||
const lines = output.split('\n');
|
||||
const processIdLine = lines.find(line => line.includes(appName));
|
||||
if (!processIdLine) {
|
||||
return;
|
||||
}
|
||||
const processId = parseInt(processIdLine.split(/\s+/)[1], 10);
|
||||
execSync(`taskkill /F /PID ${processId}`);
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
|
||||
export function removeEmptyValues(obj: any): any {
|
||||
for (const key in obj) {
|
||||
const value = obj[key];
|
||||
if (!value || typeof value !== 'number' ||
|
||||
typeof value !== 'boolean' ||
|
||||
typeof value !== 'string') {
|
||||
delete obj[key];
|
||||
}
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
export const equalFiles = (pathA, pathB) => {
|
||||
if (!exists(pathA) || !exists(pathB)) {
|
||||
return false
|
||||
}
|
||||
let statA = fs.lstatSync(pathA)
|
||||
let statB = fs.lstatSync(pathB)
|
||||
if (statA.size !== statB.size) {
|
||||
return false
|
||||
};
|
||||
let fdA = fs.openSync(pathA, 'r')
|
||||
let fdB = fs.openSync(pathB, 'r')
|
||||
let bufA = Buffer.alloc(BUF_SIZE_CMP)
|
||||
let bufB = Buffer.alloc(BUF_SIZE_CMP)
|
||||
let readA = 1
|
||||
let readB = 1
|
||||
while (readA > 0) {
|
||||
readA = fs.readSync(fdA, bufA, 0, bufA.length, null)
|
||||
readB = fs.readSync(fdB, bufB, 0, bufB.length, null)
|
||||
if (readA !== readB) {
|
||||
return false
|
||||
}
|
||||
for (let i = 0; i < readA; i++) {
|
||||
if (bufA[i] !== bufB[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
fs.closeSync(fdA)
|
||||
fs.closeSync(fdB)
|
||||
return true
|
||||
}
|
||||
0
packages/cad/src/commands/index.ts
Normal file
0
packages/cad/src/commands/index.ts
Normal file
26
packages/cad/src/commands/info.ts
Normal file
26
packages/cad/src/commands/info.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import * as CLI from 'yargs'
|
||||
|
||||
import { CONFIG_DEFAULT, DEFAULT_ROOTS } from '@plastichub/osr-commons';
|
||||
import { logger } from '../'
|
||||
|
||||
const defaultOptions = (yargs: CLI.Argv) => {
|
||||
return yargs.option('debug', {
|
||||
default: 'false',
|
||||
describe: 'debug messages'
|
||||
}).option('env_key', {
|
||||
default: 'OSR-CONFIG',
|
||||
describe: 'Environment key to the config path'
|
||||
})
|
||||
}
|
||||
|
||||
let options = (yargs: CLI.Argv) => defaultOptions(yargs);
|
||||
|
||||
export const register = (cli: CLI.Argv) => {
|
||||
return cli.command('info', 'info', options, async (argv: CLI.Arguments) => {
|
||||
if (argv.help) { return }
|
||||
const args: any = argv
|
||||
const src = CONFIG_DEFAULT(args.env_key)
|
||||
logger.debug(`Reading OSR Config with key "${argv.env_key}"`, src)
|
||||
logger.debug(`OSR Paths:`, DEFAULT_ROOTS)
|
||||
})
|
||||
}
|
||||
54
packages/cad/src/commands/pack.ts
Normal file
54
packages/cad/src/commands/pack.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import * as CLI from 'yargs'
|
||||
import { logger } from '../'
|
||||
import { SolidworkOptions } from '../types'
|
||||
import { sanitizeSingle } from '../sw_argv'
|
||||
import { pack } from '../cad/index'
|
||||
|
||||
export const defaultOptions = (yargs: CLI.Argv) => {
|
||||
return yargs.option('src', {
|
||||
default: './',
|
||||
describe: 'The source directory or source file. Glob patters are supported!',
|
||||
demandOption: true
|
||||
}).option('dst', {
|
||||
describe: 'Destination folder or file'
|
||||
}).option('view', {
|
||||
default: 'Isometric',
|
||||
describe: 'Sets the target view'
|
||||
}).option('Report', {
|
||||
describe: 'Optional conversion report. Can be JSON, HTML, CSV or Markdown'
|
||||
}).option('debug', {
|
||||
default: false,
|
||||
describe: 'Enable internal debug messages',
|
||||
type: 'boolean'
|
||||
}).option('skip', {
|
||||
default: true,
|
||||
describe: 'Skip existing files',
|
||||
type: 'boolean',
|
||||
}).option('dry', {
|
||||
default: false,
|
||||
describe: 'Run without conversion but create reports',
|
||||
type: 'boolean'
|
||||
}).option('alt', {
|
||||
default: false,
|
||||
describe: 'Alternate tokenizer'
|
||||
}).option('verbose', {
|
||||
default: true,
|
||||
describe: 'Show internal messages',
|
||||
type: 'boolean'
|
||||
}).option('sw', {
|
||||
describe: 'Set explicit the path to the Solidworks binaries & scripts.\
|
||||
"It assumes SolidWorks.Interop.sldworks.dll and export.cmd at this location!'
|
||||
}).option('script', {
|
||||
describe: 'Set explicit the path to the Solidworks script'
|
||||
})
|
||||
}
|
||||
let options = (yargs: CLI.Argv) => defaultOptions(yargs)
|
||||
export const register = (cli: CLI.Argv) => {
|
||||
return cli.command('pack', '', options, async (argv: CLI.Arguments) => {
|
||||
if (argv.help) { return }
|
||||
const options = sanitizeSingle(argv) as SolidworkOptions
|
||||
logger.setSettings({ minLevel: options.logLevel as any})
|
||||
logger.debug("options " + argv.dst, options)
|
||||
return pack(options) as any
|
||||
})
|
||||
}
|
||||
70
packages/cad/src/commands/slice.ts
Normal file
70
packages/cad/src/commands/slice.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import * as CLI from 'yargs'
|
||||
import * as path from 'path'
|
||||
import { logger } from '..'
|
||||
import { SlicerOptions } from '../types'
|
||||
import { defaultOptions, sanitize } from '../slic3r_argv'
|
||||
import { convert } from '../print'
|
||||
import { load } from 'js-yaml'
|
||||
|
||||
import { clone } from "@plastichub/core/objects"
|
||||
|
||||
import { sync as read } from "@plastichub/fs/read"
|
||||
|
||||
const SLIC3R_DEFAULTS = () => path.resolve(path.join(__dirname, '../profiles/slic3r_defaults.yaml'))
|
||||
|
||||
const defaults = (defaults, options) => {
|
||||
|
||||
let key,
|
||||
returnObject
|
||||
|
||||
returnObject = clone(options) || {}
|
||||
|
||||
for (key in defaults)
|
||||
if (defaults.hasOwnProperty(key) &&
|
||||
typeof returnObject[key] === 'undefined')
|
||||
returnObject[key] = defaults[key]
|
||||
|
||||
return returnObject
|
||||
}
|
||||
|
||||
export const register = (cli: CLI.Argv) => {
|
||||
|
||||
const defaults_path = SLIC3R_DEFAULTS()
|
||||
|
||||
cli.parserConfiguration({
|
||||
"short-option-groups": true,
|
||||
"camel-case-expansion": false
|
||||
})
|
||||
|
||||
const defaultsRaw = read(defaults_path) as string
|
||||
let defaults_json: any = load(defaultsRaw)
|
||||
let options: any = (yargs: CLI.Argv) => {
|
||||
let opts = defaultOptions(yargs)
|
||||
Object.keys(defaults_json.properties).forEach((k) => {
|
||||
const val = defaults_json.properties[k]
|
||||
switch (defaults_json.properties[k].type) {
|
||||
case 'object':
|
||||
case 'boolean':
|
||||
case 'number':
|
||||
case 'string': {
|
||||
opts = opts.option(k, val)
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return opts
|
||||
}
|
||||
|
||||
return cli.command('slice', 'Run Slic3r', options, async (argv: CLI.Arguments) => {
|
||||
if (argv.help) { return }
|
||||
|
||||
let options = sanitize(argv) as SlicerOptions
|
||||
|
||||
options = defaults(defaults_json, options)
|
||||
|
||||
options.debug && logger.info("options " + argv.dst, options)
|
||||
|
||||
return convert(options)
|
||||
})
|
||||
}
|
||||
18
packages/cad/src/commands/sw-pack.ts
Normal file
18
packages/cad/src/commands/sw-pack.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import * as CLI from 'yargs'
|
||||
import { logger } from '..'
|
||||
import { SolidworkOptions } from '../types'
|
||||
import { defaultOptions, sanitize } from '../sw_argv'
|
||||
import { convert } from '../cad/index'
|
||||
|
||||
let options = (yargs: CLI.Argv) => defaultOptions(yargs)
|
||||
|
||||
export const register = (cli: CLI.Argv) => {
|
||||
|
||||
return cli.command('sw-pack', 'Pack and Go - Using the Zip option to preserve folder structure', options, async (argv: CLI.Arguments) => {
|
||||
if (argv.help) { return }
|
||||
const options = sanitize(argv) as SolidworkOptions
|
||||
|
||||
options.debug && logger.info("options " + argv.dst, options)
|
||||
return convert(options)
|
||||
})
|
||||
}
|
||||
17
packages/cad/src/commands/sw.ts
Normal file
17
packages/cad/src/commands/sw.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import * as CLI from 'yargs'
|
||||
import { logger } from '..'
|
||||
import { SolidworkOptions } from '../types'
|
||||
import { defaultOptions, sanitize } from '../sw_argv'
|
||||
import { convert } from '../cad'
|
||||
|
||||
let options = (yargs: CLI.Argv) => defaultOptions(yargs)
|
||||
|
||||
export const register = (cli: CLI.Argv) => {
|
||||
return cli.command('sw', 'Convert CAD files via Solidworks Interop API', options, async (argv: CLI.Arguments) => {
|
||||
if (argv.help) { return }
|
||||
const options = sanitize(argv) as SolidworkOptions
|
||||
logger.setSettings({ minLevel: options.logLevel as any })
|
||||
logger.info("options " + argv.dst, options)
|
||||
return convert(options) as any
|
||||
})
|
||||
}
|
||||
7
packages/cad/src/constants.ts
Normal file
7
packages/cad/src/constants.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export const GIT_CHANGELOG_MESSAGE_PREFIX = 'ChangeLog:'
|
||||
export const GIT_REPO = 'https://git.osr-plastic.org/osr-plastic/'
|
||||
export const MODULE_NAME = `OSR-CAD`
|
||||
export const PACKAGE_NAME = 'osr-cad'
|
||||
export const DEFAULT_REPORT = '${SRC_DIR}/cad-report-${CONFIGURATION}.json'
|
||||
export const BUF_SIZE_CMP = 16 * 1024
|
||||
export const MSG_FAILED_TO_LOAD = 'Failed to load'
|
||||
14
packages/cad/src/index.ts
Normal file
14
packages/cad/src/index.ts
Normal file
@ -0,0 +1,14 @@
|
||||
export * from './log'
|
||||
export * from './types'
|
||||
export * from './cad/sw-lib'
|
||||
export * from './_cli'
|
||||
export * from './sw_argv'
|
||||
export * from './lib/geometry/dxf'
|
||||
|
||||
import { logger as _logger } from '@plastichub/core/debug'
|
||||
import { MODULE_NAME } from './constants'
|
||||
|
||||
export const logger = _logger(MODULE_NAME)
|
||||
import { substitute as _substitute , substituteAlt as _substituteAlt } from "@plastichub/core/strings"
|
||||
import { IObjectLiteral } from "@plastichub/core"
|
||||
export const substitute = (alt:boolean, template:string, vars:IObjectLiteral) => alt ? _substituteAlt(template,vars) : _substitute(template, vars)
|
||||
1
packages/cad/src/lib/cache.ts
Normal file
1
packages/cad/src/lib/cache.ts
Normal file
@ -0,0 +1 @@
|
||||
export const get = (str:string, dst:string ) => {}
|
||||
18
packages/cad/src/lib/formatter.ts
Normal file
18
packages/cad/src/lib/formatter.ts
Normal file
@ -0,0 +1,18 @@
|
||||
export const sizeToString = (bytes: number, si: boolean = true) => {
|
||||
var units;
|
||||
var u;
|
||||
var b = bytes;
|
||||
var thresh = si ? 1000 : 1024;
|
||||
if (Math.abs(b) < thresh) {
|
||||
return b + ' B';
|
||||
}
|
||||
units = si
|
||||
? ['kB', 'MB', 'GB', 'TB']
|
||||
: ['KiB', 'MiB', 'GiB', 'TiB'];
|
||||
u = -1;
|
||||
do {
|
||||
b /= thresh;
|
||||
++u;
|
||||
} while (Math.abs(b) >= thresh && u < units.length - 1);
|
||||
return b.toFixed(1) + ' ' + units[u];
|
||||
};
|
||||
68
packages/cad/src/lib/geometry/dxf.ts
Normal file
68
packages/cad/src/lib/geometry/dxf.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import * as fs from 'fs';
|
||||
const dxf = require('dxf-parser')
|
||||
import { sync as read } from '@plastichub/fs/read'
|
||||
import { sync as write } from '@plastichub/fs/write'
|
||||
|
||||
interface DxfEntity {
|
||||
type: string;
|
||||
vertices?: { x: number; y: number }[];
|
||||
start?: { x: number; y: number };
|
||||
end?: { x: number; y: number };
|
||||
radius?: number;
|
||||
center?: { x: number; y: number };
|
||||
startAngle?: number;
|
||||
endAngle?: number;
|
||||
}
|
||||
|
||||
function distanceBetweenPoints(p1: { x: number; y: number }, p2: { x: number; y: number }): number {
|
||||
return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
|
||||
}
|
||||
|
||||
function arcLength(radius: number, startAngle: number, endAngle: number): number {
|
||||
return Math.abs(endAngle - startAngle) * radius;
|
||||
}
|
||||
|
||||
function calculateEntityLength(entity: DxfEntity): number {
|
||||
switch (entity.type) {
|
||||
//case 'LINE':
|
||||
// return distanceBetweenPoints(entity.start!, entity.end!);
|
||||
case 'LWPOLYLINE':
|
||||
case 'LINE':
|
||||
let length = 0;
|
||||
for (let i = 0; i < entity.vertices!.length - 1; i++) {
|
||||
try {
|
||||
length += distanceBetweenPoints(entity.vertices![i], entity.vertices![i + 1]);
|
||||
} catch (e) {
|
||||
console.log('error', entity, e)
|
||||
|
||||
}
|
||||
}
|
||||
return length;
|
||||
case 'CIRCLE':
|
||||
return 2 * Math.PI * entity.radius!;
|
||||
case 'ARC':
|
||||
return arcLength(entity.radius!, entity.startAngle!, entity.endAngle!);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function calculateTotalDxfEntitiesLength(filePath: string): number {
|
||||
const parser = new dxf();
|
||||
const dxfData = parser.parseSync(fs.readFileSync(filePath, 'utf-8'));
|
||||
|
||||
const ret = dxfData.entities.reduce((totalLength: number, entity: DxfEntity) => {
|
||||
console.log('entity', entity)
|
||||
const length = calculateEntityLength(entity);
|
||||
return totalLength + length;
|
||||
}, 0);
|
||||
write( filePath + '.json', JSON.stringify(dxfData, null, 2))
|
||||
return ret;
|
||||
}
|
||||
|
||||
const test = () => {
|
||||
// Usage example
|
||||
const filePath = './tests/dxf/square-200-bore.DXF'
|
||||
const totalLength = calculateTotalDxfEntitiesLength(filePath);
|
||||
console.log(`Total length of all entities: ${totalLength}`);
|
||||
}
|
||||
14
packages/cad/src/lib/index.ts
Normal file
14
packages/cad/src/lib/index.ts
Normal file
@ -0,0 +1,14 @@
|
||||
export const removeEmpty = (data) => {
|
||||
//transform properties into key-values pairs and filter all the empty-values
|
||||
const entries = Object.entries(data).filter(([, value]) => value != null);
|
||||
|
||||
//map through all the remaining properties and check if the value is an object.
|
||||
//if value is object, use recursion to remove empty properties
|
||||
const clean = entries.map(([key, v]) => {
|
||||
const value = typeof v == 'object' ? removeEmpty(v) : v
|
||||
return [key, value]
|
||||
})
|
||||
|
||||
//transform the key-value pairs back to an object.
|
||||
return Object.fromEntries(clean)
|
||||
}
|
||||
140
packages/cad/src/lib/process/index.ts
Normal file
140
packages/cad/src/lib/process/index.ts
Normal file
@ -0,0 +1,140 @@
|
||||
import { logger } from '../../index'
|
||||
import * as stream from 'stream';
|
||||
import { ChildProcess, exec } from 'child_process';
|
||||
|
||||
export enum STATUS {
|
||||
OK,
|
||||
ERROR,
|
||||
PENDING
|
||||
}
|
||||
|
||||
const fatalHandler = (message: string, fn: (msg: string) => void): boolean => {
|
||||
if (message.startsWith('fatal:')) {
|
||||
fn('\t\ ' + message)
|
||||
return true;
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// tslint:disable-next-line:no-empty
|
||||
const subscribe = (signal: stream.Readable, collector: (data: any) => void = () => { }, options: any = {}) => {
|
||||
const buffer: string[] = []
|
||||
signal.on('message', (message) => logger.debug('message', message))
|
||||
signal.on('error', (error) => logger.error('std-error', error))
|
||||
signal.on('data', (data) => {
|
||||
const message = data.toString()
|
||||
buffer.push(message) // .replace(/[\x00-\x1F\x7F-\x9F]/g, "")
|
||||
collector(buffer)
|
||||
logger.debug("\n Process : \n\t", data)
|
||||
});
|
||||
};
|
||||
const merge = (buffer: string[], data: any): string[] => buffer.concat(data);
|
||||
|
||||
const hook = (process: ChildProcess, resolve: any, reject: any, cmd: string, options: any = {}) => {
|
||||
let buffer: string[] = [];
|
||||
const collector = (data: any) => { buffer = buffer.concat(data); };
|
||||
subscribe(process.stdout, collector, options);
|
||||
subscribe(process.stderr, collector, options);
|
||||
process.on('exit', (code, signal) => {
|
||||
if (code) {
|
||||
resolve({
|
||||
code: STATUS.ERROR,
|
||||
command: cmd,
|
||||
error: code,
|
||||
messages: buffer
|
||||
})
|
||||
} else {
|
||||
resolve({
|
||||
code: STATUS.OK,
|
||||
command: cmd,
|
||||
messages: buffer
|
||||
})
|
||||
}
|
||||
})
|
||||
return process
|
||||
}
|
||||
|
||||
export class Process {
|
||||
public binary = 'magick';
|
||||
public cwd: string = '';
|
||||
public args: string = '';
|
||||
constructor(options: any = {}) {
|
||||
this.binary = options.binary || this.binary;
|
||||
this.cwd = options.cwd || process.cwd();
|
||||
}
|
||||
public optionsToString(options: any): string {
|
||||
const args: any[] = [];
|
||||
// tslint:disable-next-line:forin
|
||||
for (const k in options) {
|
||||
const val = options[k];
|
||||
if (k.length === 1) {
|
||||
// val is true, add '-k'
|
||||
if (val === true) {
|
||||
args.push('-' + k);
|
||||
} else if (val !== false) {
|
||||
// if val is not false, add '-k val'
|
||||
args.push('-' + k + ' ' + val);
|
||||
}
|
||||
} else {
|
||||
if (val === true) {
|
||||
args.push('--' + k);
|
||||
} else if (val !== false) {
|
||||
args.push('--' + k + '=' + val);
|
||||
}
|
||||
}
|
||||
}
|
||||
return args.join(' ');
|
||||
}
|
||||
public optionsToArray(options: any): string[] {
|
||||
const args: any[] = []
|
||||
// tslint:disable-next-line:forin
|
||||
for (const k in options) {
|
||||
const val = options[k]
|
||||
if (k.length === 1) {
|
||||
// val is true, add '-k'
|
||||
if (val === true) {
|
||||
args.push('-' + k)
|
||||
} else if (val !== false) {
|
||||
// if val is not false, add '-k val'
|
||||
args.push('-' + k + ' ' + val)
|
||||
}
|
||||
} else {
|
||||
if (val === true) {
|
||||
args.push('--' + k);
|
||||
} else if (val !== false) {
|
||||
args.push('--' + k + '=' + val)
|
||||
}
|
||||
}
|
||||
}
|
||||
return args
|
||||
}
|
||||
public async exec(command: string, options: any = {}, args: any[] = []): Promise<any> {
|
||||
args = [command].concat(args)
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
const p = exec(this.binary + ' ' + args.join(' '), {
|
||||
cwd: this.cwd
|
||||
})
|
||||
return hook(p, resolve, reject, this.binary + ' ' + args.join(' '), options)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Helper {
|
||||
public static async run(cwd, command: string, args: string[], debug_stream: boolean = false): Promise<any> {
|
||||
logger.trace(`Run ${command} in ${cwd} ${args.join(' ')}`)
|
||||
const gitProcess = new Process({
|
||||
cwd: cwd,
|
||||
binary: command
|
||||
})
|
||||
const p = gitProcess.exec('', {
|
||||
debug: debug_stream
|
||||
}, args)
|
||||
|
||||
if (!debug_stream) {
|
||||
p.catch((e) => logger.error('Error git command : ' + command, e))
|
||||
} else {
|
||||
logger.trace(command + ' ' + args.join(' '))
|
||||
}
|
||||
return p
|
||||
}
|
||||
}
|
||||
1
packages/cad/src/log.ts
Normal file
1
packages/cad/src/log.ts
Normal file
@ -0,0 +1 @@
|
||||
export const noop = () => {}
|
||||
18
packages/cad/src/main.ts
Normal file
18
packages/cad/src/main.ts
Normal file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env node
|
||||
import { defaults } from './_cli'; defaults()
|
||||
|
||||
import * as cli from 'yargs'
|
||||
|
||||
import { register as registerSW } from './commands/sw'; registerSW(cli as any)
|
||||
import { register as registerSlic3r } from './commands/slice'; registerSlic3r(cli as any)
|
||||
import { register as registerPack } from './commands/pack'; registerPack(cli as any)
|
||||
import { register as registerInfo } from './commands/info'; registerInfo(cli as any)
|
||||
|
||||
const argv: any = cli.argv
|
||||
|
||||
if (argv.h || argv.help) {
|
||||
cli.showHelp()
|
||||
process.exit()
|
||||
} else if (argv.v || argv.version) {
|
||||
process.exit()
|
||||
}
|
||||
106
packages/cad/src/os/context_menu/register_cli.ts
Normal file
106
packages/cad/src/os/context_menu/register_cli.ts
Normal file
@ -0,0 +1,106 @@
|
||||
const Registry = require('rage-edit').Registry;
|
||||
|
||||
const SOFTWARE_CLASSES = 'HKCU\\Software\\Classes\\';
|
||||
|
||||
export const registerCommand = async options => {
|
||||
if (!options) throw new Error('options are empty');
|
||||
|
||||
const { name, icon, command, menu } = options;
|
||||
if (!name) throw new Error('name is not specified');
|
||||
if (!command) throw new Error('command is not specified');
|
||||
if (!menu) throw new Error('menuName is not specified');
|
||||
|
||||
try {
|
||||
await Registry.set(`${SOFTWARE_CLASSES}*\\shell\\${name}`);
|
||||
await Registry.set(`${SOFTWARE_CLASSES}*\\shell\\${name}`, '', menu);
|
||||
if (icon) await Registry.set(`${SOFTWARE_CLASSES}*\\shell\\${name}`, 'Icon', (icon.endsWith('.exe') ? `${icon},0` : icon));
|
||||
await Registry.set(`${SOFTWARE_CLASSES}*\\shell\\${name}\\command`, '', `"${command}" "%1"`);
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
export const registerDirectoryCommand = async options => {
|
||||
if (!options) throw new Error('options are empty');
|
||||
|
||||
const { name, icon, command, menu } = options;
|
||||
if (!name) throw new Error('name is not specified');
|
||||
if (!command) throw new Error('command is not specified');
|
||||
if (!menu) throw new Error('menu is not specified');
|
||||
|
||||
try {
|
||||
await Registry.set(`${SOFTWARE_CLASSES}Directory\\shell\\${name}`);
|
||||
await Registry.set(`${SOFTWARE_CLASSES}Directory\\shell\\${name}`, '', menu);
|
||||
if (icon) await Registry.set(`${SOFTWARE_CLASSES}Directory\\shell\\${name}`, 'Icon', (icon.endsWith('.exe') ? `${icon},0` : icon));
|
||||
await Registry.set(`${SOFTWARE_CLASSES}Directory\\shell\\${name}\\command`, '', `"${command}" "%1"`);
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
export const registerOpenWithCommand = async (extensions, options) => {
|
||||
if (!extensions || !extensions.length) throw new Error('extensions is not specified');
|
||||
if (!options) throw new Error('options are empty');
|
||||
|
||||
const { name, command } = options;
|
||||
if (!name) throw new Error('name is not specified');
|
||||
if (!command) throw new Error('command is not specified');
|
||||
|
||||
try {
|
||||
await Promise.all((await findExtensionNames(extensions)).map(async n => {
|
||||
await Registry.set(`${SOFTWARE_CLASSES}${n}`);
|
||||
await Registry.set(`${SOFTWARE_CLASSES}${n}\\shell\\${name}`);
|
||||
await Registry.set(`${SOFTWARE_CLASSES}${n}\\shell\\${name}\\command`, '', `"${command}" "%1"`);
|
||||
}));
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
export const removeCommand = async name => {
|
||||
if (!name) throw new Error('name is not specified');
|
||||
|
||||
try {
|
||||
await Registry.delete(`${SOFTWARE_CLASSES}*\\shell\\${name}`);
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
export const removeDirectoryCommand = async name => {
|
||||
if (!name) throw new Error('name is not specified');
|
||||
|
||||
try {
|
||||
await Registry.delete(`${SOFTWARE_CLASSES}Directory\\shell\\${name}`);
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
export const removeOpenWithCommand = async (extensions, name) => {
|
||||
if (!extensions) throw new Error('extensions is not specified');
|
||||
if (!name) throw new Error('name is not specified');
|
||||
|
||||
try {
|
||||
await Promise.all((await findExtensionNames(extensions)).map(async n => await Registry.delete(`${SOFTWARE_CLASSES}${n}\\shell\\${name}`)));
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
async function findExtensionNames (exts) {
|
||||
const { ses_root } = await Registry.get('HKCR');
|
||||
return Promise.all(Object.keys(ses_root).filter(e => exts.includes(e)).map(async k => (await Registry.get(`HKCR\\${k}`)).$values['']));
|
||||
}
|
||||
1
packages/cad/src/print/index.ts
Normal file
1
packages/cad/src/print/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { convert } from './slic3r'
|
||||
404
packages/cad/src/print/slic3r.ts
Normal file
404
packages/cad/src/print/slic3r.ts
Normal file
@ -0,0 +1,404 @@
|
||||
import * as path from 'path'
|
||||
import { logger, substitute } from '..'
|
||||
import { removeEmpty } from '../lib'
|
||||
import { OSR_CACHE } from '@plastichub/osr-commons'
|
||||
import { sync as exists } from "@plastichub/fs/exists"
|
||||
import { sync as read } from "@plastichub/fs/read"
|
||||
import { sync as write } from "@plastichub/fs/write"
|
||||
import { sync as dir } from "@plastichub/fs/dir"
|
||||
import { Promise as BPromise } from 'bluebird'
|
||||
import { sync as which } from 'which'
|
||||
import * as md5 from 'md5'
|
||||
|
||||
import { SlicerOptions } from '../types'
|
||||
import { Helper } from '../lib/process/index'
|
||||
|
||||
import { reportCSV } from '../report'
|
||||
|
||||
import {
|
||||
get_cached,
|
||||
set_cached
|
||||
} from '@plastichub/osr-cache/lib'
|
||||
|
||||
import {
|
||||
MODULE_NAME
|
||||
} from '../constants'
|
||||
|
||||
|
||||
export const fileAsBuffer = (path: string) => read(path, 'buffer') as Buffer || Buffer.from("-")
|
||||
|
||||
const SLIC3R_EXE = 'Slic3r-console.exe'
|
||||
|
||||
const clone = (obj) => {
|
||||
if (null == obj || "object" != typeof obj) return obj;
|
||||
var copy = obj.constructor();
|
||||
for (var attr in obj) {
|
||||
if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
export const getSlicrDir = (options: SlicerOptions) => {
|
||||
const dir = path.parse(which(SLIC3R_EXE)).dir
|
||||
if (exists(dir)) {
|
||||
return dir
|
||||
}
|
||||
}
|
||||
|
||||
export const getBin = (options: SlicerOptions) => {
|
||||
const dir = getSlicrDir(options)
|
||||
const exe = path.resolve(path.join(dir, SLIC3R_EXE))
|
||||
if (exists(exe)) {
|
||||
return exe
|
||||
}
|
||||
}
|
||||
|
||||
const toPercentString = (aNumber) => String(aNumber * 100) + '%'
|
||||
|
||||
export const convertFile = async (file, target, onNode: (data: any) => void = () => { }, options: SlicerOptions) => {
|
||||
|
||||
let bin = getBin(options)
|
||||
if (!bin) {
|
||||
logger.error(`Cant find Slicr. Please register the directory in your $PATH environment variable!`)
|
||||
return
|
||||
}
|
||||
|
||||
const getArgs = (o: SlicerOptions) => {
|
||||
return [
|
||||
`--output "${target}"`,
|
||||
// Non-slicing actions
|
||||
o.repair ? '--repair' : '',
|
||||
o.cut ? '--cut' : '',
|
||||
o.split ? '--split' : '',
|
||||
o.info ? '--info' : '',
|
||||
'--threads ' + o.threads,
|
||||
|
||||
// Output options
|
||||
o.outputFilenameFormat ?
|
||||
'--output-filename-format ' + o.outputFilenameFormat : '',
|
||||
o.postProcess ? o.postProcessScripts.map(function (script) {
|
||||
return '--post-process ' + script
|
||||
}).join(' ') : '',
|
||||
o.exportSvg ? '--export-svg' : '',
|
||||
o.merge ? '--merge' : '',
|
||||
|
||||
// Printer options
|
||||
'--nozzle-diameter ' + o.nozzleDiameter,
|
||||
'--print-center ' + o.printCenter.x + ',' + o.printCenter.y,
|
||||
'--z-offset ' + o.zOffset,
|
||||
'--gcode-flavor ' + o.GCodeFlavor,
|
||||
o.useRelativeEDistances ? '--use-relative-e-distances ' : '',
|
||||
o.useFirmwareRetraction ? '--use-firmware-retraction ' : '',
|
||||
o.useVolumetricE ? '--use-volumetric-e ' : '',
|
||||
o.GCodeArcs ? '--gcode-arcs' : '',
|
||||
o.g0 ? '--g0' : '',
|
||||
o.GCodeComments ? '--gcode-comments' : '',
|
||||
'--vibration-limit ' + o.vibrationLimit,
|
||||
//'--pressure-advance ' + o.pressureAdvance,
|
||||
|
||||
// Filament options
|
||||
'--filament-diameter ' + o.filamentDiameter,
|
||||
'--extrusion-multiplier ' + o.extrusionMultiplier,
|
||||
'--temperature ' + o.temperature,
|
||||
'--first-layer-temperature ' + o.firstLayerTemperature,
|
||||
'--bed-temperature ' + o.bedTemperature,
|
||||
'--first-layer-bed-temperature ' + o.firstLayerBedTemperature,
|
||||
|
||||
// Speed options
|
||||
'--travel-speed ' + o.travelSpeed,
|
||||
'--perimeter-speed ' + o.perimeterSpeed,
|
||||
'--small-perimeter-speed ' + o.smallPerimeterSpeed,
|
||||
'--external-perimeter-speed ' + o.externalPerimeterSpeed,
|
||||
'--infill-speed ' + o.infillSpeed,
|
||||
'--solid-infill-speed ' + o.solidInfillSpeed,
|
||||
'--top-solid-infill-speed ' + o.topSolidInfillSpeed,
|
||||
'--support-material-speed ' + o.supportMaterialSpeed,
|
||||
'--support-material-interface-speed ' + o.supportMaterialInterfaceSpeed,
|
||||
'--bridge-speed ' + o.bridgeSpeed,
|
||||
'--gap-fill-speed ' + o.gapFillSpeed,
|
||||
'--first-layer-speed ' + o.firstLayerSpeed,
|
||||
|
||||
// Accelerator options
|
||||
'--perimeter-acceleration ' + o.perimeterAcceleration,
|
||||
'--infill-acceleration ' + o.infillAcceleration,
|
||||
'--bridge-acceleration ' + o.bridgeAcceleration,
|
||||
'--first-layer-acceleration ' + o.firstLayerAcceleration,
|
||||
'--default-acceleration ' + o.defaultAcceleration,
|
||||
|
||||
// Accuracy options
|
||||
'--layer-height ' + o.layerHeight,
|
||||
'--first-layer-height ' + o.firstLayerHeight,
|
||||
'--infill-every-layers ' + o.infillEveryLayers,
|
||||
'--solid-infill-every-layers ' + o.solidInfillEveryLayers,
|
||||
|
||||
// Print Options
|
||||
'--perimeters ' + o.perimeters,
|
||||
'--top-solid-layers ' + o.topSolidLayers,
|
||||
'--bottom-solid-layers ' + o.bottomSolidLayers,
|
||||
o.solidLayers ? '--solid-layers' : '',
|
||||
'--fill-density ' + toPercentString(o.fillDensity),
|
||||
'--fill-angle ' + o.fillAngle,
|
||||
'--fill-pattern ' + o.fillPattern,
|
||||
'--solid-fill-pattern ' + o.solidFillPattern,
|
||||
o.startGcode ? '--start-gcode' : '',
|
||||
o.endGcode ? '--end-gcode ' : '',
|
||||
o.layerGcode ? '--layer-gcode ' : '',
|
||||
o.toolchangeGcode ? '--toolchange-gcode ' : '',
|
||||
'--seam-position ' + o.seamPosition,
|
||||
o.externalPerimetersFirst ? '--external-perimeters-first ' : '',
|
||||
o.spiralVase ? '--spiral-vase ' : '',
|
||||
o.onlyRetractWhenCrossingPerimeters ?
|
||||
'--only-retract-when-crossing-perimeters ' : '',
|
||||
'--solid-infill-below-area ' + o.solidInfillBelowArea,
|
||||
o.infillOnlyWhereNeeded ? '--infill-only-where-needed ' : '',
|
||||
o.infillFirst ? '--infill-first ' : '',
|
||||
|
||||
// Quality options
|
||||
o.extraPerimeters ? '--extra-perimeters' : '',
|
||||
o.avoidCrossingPerimeters ? '--avoid-crossing-perimeters' : '',
|
||||
o.thinWalls ? '--thin-walls' : '',
|
||||
o.overhangs ? '--overhangs' : '',
|
||||
|
||||
// Support material options
|
||||
o.supportMaterial ? '--support-material ' : '',
|
||||
'--support-material-threshold ' + o.supportMaterialThreshold,
|
||||
'--support-material-pattern ' + o.supportMaterialPattern,
|
||||
'--support-material-spacing ' + o.supportMaterialSpacing,
|
||||
'--support-material-angle ' + o.supportMaterialAngle,
|
||||
'--support-material-interface-layers ' +
|
||||
o.supportMaterialInterfaceLayers,
|
||||
'--support-material-interface-spacing ' +
|
||||
o.supportMaterialInterfaceSpacing,
|
||||
'--raft-layers ' + o.raftLayers,
|
||||
'--support-material-enforce-layers ' + o.supportMaterialEnforceLayers,
|
||||
o.dontSupportBridges ? '--dont-support-bridges ' : '',
|
||||
|
||||
// Retraction options
|
||||
'--retract-length ' + o.retractLength,
|
||||
'--retract-speed ' + o.retractSpeed,
|
||||
'--retract-restart-extra ' + o.retractRestartExtra,
|
||||
'--retract-before-travel ' + o.retractBeforeTravel,
|
||||
'--retract-lift ' + o.retractLift,
|
||||
o.retractLayerChange ? '--retract-layer-change' : '',
|
||||
o.wipe ? '--wipe' : '',
|
||||
|
||||
// Retraction options for multi-extruder setups
|
||||
'--retract-length-toolchange ' + o.retractLengthToolchange,
|
||||
'--retract-restart-extra-toolchange ' + o.retractRestartExtraToolchange,
|
||||
|
||||
// Cooling options
|
||||
o.cooling ? '--cooling ' : ' ',
|
||||
'--min-fan-speed ' + (o.minFanSpeed * 100), // in %
|
||||
'--max-fan-speed ' + (o.maxFanSpeed * 100), // in %
|
||||
'--bridge-fan-speed ' + (o.bridgeFanSpeed * 100), // in %
|
||||
'--fan-below-layer-time ' + o.fanBelowLayerTime,
|
||||
'--slowdown-below-layer-time ' + o.slowdownBelowLayerTime,
|
||||
'--min-print-speed ' + o.minPrintSpeed,
|
||||
'--disable-fan-first-layers ' + o.disableFanFirstLayers,
|
||||
o.fanAlwaysOn ? '--fan-always-on ' : '',
|
||||
|
||||
// Skirt options
|
||||
'--skirts ' + o.skirts,
|
||||
'--skirt-distance ' + o.skirtDistance,
|
||||
'--skirt-height ' + o.skirtHeight,
|
||||
'--min-skirt-length ' + o.minSkirtLength,
|
||||
'--brim-width ' + o.brimWidth,
|
||||
|
||||
// Transform options
|
||||
'--scale ' + o.scale,
|
||||
'--rotate ' + o.rotate,
|
||||
'--duplicate ' + o.duplicate,
|
||||
'--duplicate-grid ' + o.duplicateGrid,
|
||||
'--duplicate-distance ' + o.duplicateDistance,
|
||||
//'--xy-size-compensation ' + o.xySizeCompensation,
|
||||
|
||||
// Sequential printing options
|
||||
o.completeObjects ? '--complete-objects ' : '',
|
||||
'--extruder-clearance-radius ' + o.extruderClearanceRadius,
|
||||
'--extruder-clearance-height ' + o.extruderClearanceHeight,
|
||||
|
||||
// Miscellaneous options:
|
||||
o.notes ? '--notes ' + o.notes : '',
|
||||
'--resolution ' + o.resolution,
|
||||
// '--bed-size ' + o.bedSize.width + ',' + o.bedSize.height,
|
||||
|
||||
// Flow options (advanced):
|
||||
'--extrusion-width ' + o.extrusionWidth,
|
||||
o.firstLayerExtrusionWidth ?
|
||||
'--first-layer-extrusion-width ' + o.firstLayerExtrusionWidth : '',
|
||||
'--perimeter-extrusion-width ' + o.perimeterExtrusionWidth,
|
||||
//'--external-perimeter-extrusion-width ' +
|
||||
// o.externalPerimeterExtrusionWidth,
|
||||
'--infill-extrusion-width ' + o.infillExtrusionWidth,
|
||||
'--solid-infill-extrusion-width ' + o.solidInfillExtrusionWidth,
|
||||
'--top-infill-extrusion-width ' + o.topInfillExtrusionWidth,
|
||||
'--support-material-extrusion-width ' + o.supportMaterialExtrusionWidth,
|
||||
'--bridge-flow-ratio ' + o.bridgeFlowRatio,
|
||||
|
||||
// Multiple extruder options:
|
||||
o.extruderOffset.x || o.extruderOffset.y ?
|
||||
'--extruder-offset ' + o.extruderOffset.x + 'x' +
|
||||
o.extruderOffset.y : '',
|
||||
'--perimeter-extruder ' + o.perimeterExtruder,
|
||||
'--infill-extruder ' + o.infillExtruder,
|
||||
//'--solid-infill-extruder ' + o.solidInfillExtruder,
|
||||
'--support-material-extruder ' + o.supportMaterialExtruder,
|
||||
'--support-material-interface-extruder ' +
|
||||
o.supportMaterialInterfaceExtruder,
|
||||
o.oozePrevention ? '--ooze-prevention ' : '',
|
||||
'--standby-temperature-delta ' + o.standbyTemperatureDelta,
|
||||
`"${file}"`
|
||||
]
|
||||
}
|
||||
|
||||
const osr_cache = OSR_CACHE()
|
||||
const ca_options = JSON.parse(JSON.stringify({ ...options, target, skip: null }))
|
||||
|
||||
const cached = await get_cached(file, ca_options, MODULE_NAME)
|
||||
|
||||
if (osr_cache && cached && options.cache !== false) {
|
||||
let md5Src = md5(Buffer.from(cached))
|
||||
let md5Dst = md5(fileAsBuffer(target))
|
||||
|
||||
if (!exists(target) || md5Src !== md5Dst) {
|
||||
write(target, Buffer.from(cached))
|
||||
}
|
||||
onNode({
|
||||
src: file,
|
||||
target
|
||||
})
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
let _target = '' + target
|
||||
let args = getArgs(options).filter((a)=>!!a).filter((k)=>k.indexOf('undefined')==-1)
|
||||
|
||||
const ret = await Helper.run(getSlicrDir(options), SLIC3R_EXE, args, options.debug)
|
||||
|
||||
if(ret && ret.code !==0){
|
||||
logger.error(`Error running Slic3r : `)
|
||||
return ret
|
||||
}
|
||||
|
||||
if(options.log){
|
||||
write(options.log,ret.messages.join('\n'))
|
||||
}
|
||||
|
||||
onNode({
|
||||
...ret,
|
||||
src: file,
|
||||
target
|
||||
})
|
||||
|
||||
if(options.saveArgs){
|
||||
write(options.saveArgs,`${SLIC3R_EXE} ${args.join(' ')}`)
|
||||
}
|
||||
|
||||
if(options.saveAsProfile){
|
||||
const out = clone(removeEmpty(options))
|
||||
delete out['src']
|
||||
delete out['srcInfo']
|
||||
delete out['dst']
|
||||
delete out['dstInfo']
|
||||
delete out['title']
|
||||
delete out['type']
|
||||
delete out['properties']
|
||||
delete out['oneOf']
|
||||
delete out['$0']
|
||||
delete out['_']
|
||||
delete out['skip']
|
||||
delete out['variables']
|
||||
delete out['saveAsProfile']
|
||||
delete out['saveArgs']
|
||||
delete out['profile']
|
||||
delete out['debug']
|
||||
delete out['verbose']
|
||||
delete out['log']
|
||||
write(options.saveAsProfile, out )
|
||||
}
|
||||
|
||||
if (osr_cache) {
|
||||
options.debug && logger.info('Write output to cache', _target)
|
||||
await set_cached(file, ca_options, MODULE_NAME, fileAsBuffer(_target))
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
export async function convertFiles(file, targets: string[], onNode: (data: any) => void = () => { }, options: SlicerOptions) {
|
||||
|
||||
if (options.dry) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
return BPromise.resolve(targets).map((target) => {
|
||||
return convertFile(file, target, onNode, options)
|
||||
}, { concurrency: 1 });
|
||||
|
||||
}
|
||||
|
||||
export const report = (data, dst: string) => {
|
||||
|
||||
let report: any = null;
|
||||
if (dst.endsWith('.md')) {
|
||||
//report = reportMarkdown(data);
|
||||
}
|
||||
|
||||
if (dst.endsWith('.csv')) {
|
||||
report = reportCSV(data);
|
||||
}
|
||||
|
||||
if (report) {
|
||||
logger.info(`Write report to ${dst}`);
|
||||
write(dst, report);
|
||||
}
|
||||
return report;
|
||||
}
|
||||
|
||||
export const targets = (f: string, options: SlicerOptions) => {
|
||||
const srcParts = path.parse(f)
|
||||
const variables = clone(options.variables)
|
||||
const targets = []
|
||||
if (options.dstInfo.IS_GLOB) {
|
||||
options.dstInfo.GLOB_EXTENSIONS.forEach((e) => {
|
||||
variables.SRC_NAME = srcParts.name
|
||||
variables.SRC_DIR = srcParts.dir
|
||||
let targetPath = substitute(options.alt, options.variables.DST_PATH, variables)
|
||||
targetPath = path.resolve(targetPath.replace(options.variables.DST_FILE_EXT, '') + e)
|
||||
const parts = path.parse(targetPath)
|
||||
if (!exists(parts.dir)) {
|
||||
try {
|
||||
dir(parts.dir)
|
||||
} catch (e) {
|
||||
if (options.debug) {
|
||||
logger.error(`Error creating target path ${parts.dir} for ${targetPath}`)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
targets.push(targetPath)
|
||||
});
|
||||
}
|
||||
return targets
|
||||
}
|
||||
|
||||
export async function convert(options: SlicerOptions) {
|
||||
|
||||
let reports = []
|
||||
|
||||
const onNode = options.onNode || ((data) => reports.push(data))
|
||||
|
||||
options.verbose && logger.info(`Convert ${options.srcInfo.FILES.length} files `)
|
||||
await BPromise.resolve(options.srcInfo.FILES).map((f) => {
|
||||
const outputs = targets(f, options)
|
||||
options.verbose && logger.info(`Convert ${f} to `, outputs)
|
||||
return convertFiles(f, outputs, onNode, options)
|
||||
}, { concurrency: 1 })
|
||||
|
||||
if (options.report) {
|
||||
const reportOutFile: string = substitute(false, options.report, {
|
||||
dst: options.srcInfo.DIR
|
||||
})
|
||||
options.verbose && logger.info(`Write report to ${reportOutFile}`);
|
||||
report(reports, reportOutFile)
|
||||
}
|
||||
}
|
||||
95
packages/cad/src/renderer/puppeteer/Scope.ts
Normal file
95
packages/cad/src/renderer/puppeteer/Scope.ts
Normal file
@ -0,0 +1,95 @@
|
||||
import { Browser, launch, Page, Response } from 'puppeteer';
|
||||
import { inspect, error, debug } from '../../log';
|
||||
import { capture_requests, capture_responses } from './network';
|
||||
let instance: Scope;
|
||||
import * as path from 'path';
|
||||
import { URL } from 'url';
|
||||
export const STATS_SUFFIX = '_stats.json';
|
||||
export const SESSION_EVENTS_SUFFIX = '_session.json';
|
||||
export const TRACE_SUFFIX = '_trace.json';
|
||||
const included_categories = ['devtools.timeline'];
|
||||
const _url_short = (url: string) =>
|
||||
new URL(url).hostname;
|
||||
|
||||
const _date_suffix = () =>
|
||||
new Date().toLocaleTimeString().replace(/:/g, '_');
|
||||
|
||||
const _random_suffix = () =>
|
||||
Math.random() * 100;
|
||||
|
||||
const _default_filename = (url: string) =>
|
||||
`${_url_short(url)}_${_random_suffix()}`;
|
||||
|
||||
export const default_path = (cwd: string, url: string) =>
|
||||
`${path.join(cwd, _default_filename(url))}${STATS_SUFFIX}`;
|
||||
|
||||
export const default_session_events_path = (cwd: string, url: string) =>
|
||||
`${path.join(cwd || process.cwd(), 'sessions', _default_filename(url))}${SESSION_EVENTS_SUFFIX}`;
|
||||
|
||||
export const default_trace_path = (cwd: string, url: string) =>
|
||||
`${path.join(cwd, _default_filename(url))}${TRACE_SUFFIX}`;
|
||||
|
||||
export class Scope {
|
||||
browser!: Browser;
|
||||
context!: any;
|
||||
page!: Page;
|
||||
args!: any;
|
||||
requests: any[] = [];
|
||||
responses: Response[] = [];
|
||||
eventBeacons: any[] = [];
|
||||
mutationBeacons: any[] = [];
|
||||
sessionSuffix: string = '';
|
||||
onResponse;
|
||||
onRequest;
|
||||
async init() {
|
||||
this.sessionSuffix = ' - ' + new Date().getTime();
|
||||
const args = [
|
||||
'--no-sandbox',
|
||||
'--disable-setuid-sandbox',
|
||||
'--disable-infobars',
|
||||
'--window-position=0,0',
|
||||
'--ignore-certifcate-errors',
|
||||
'--ignore-certifcate-errors-spki-list',
|
||||
'--user-agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3312.0 Safari/537.36"'
|
||||
];
|
||||
this.browser = await launch({ headless: this.args.headless === 'true', devtools: true,args:args});
|
||||
// const context = await this.browser.createIncognitoBrowserContext();
|
||||
this.page = await this.browser.newPage();
|
||||
// this.page = await context.newPage();
|
||||
|
||||
this.page.on('console', msg => {
|
||||
// error('Browser error:', msg);
|
||||
});
|
||||
this.page.on('error', msg => error('Browser Error:', msg));
|
||||
// this.page.on('pageerror', msg => error('Browser Page Error:', msg));
|
||||
// this.page.on('requestfailed', msg => error('Browser Page Request Error:', msg));
|
||||
|
||||
//capture_requests(this, this.page);
|
||||
//capture_responses(this, this.page);
|
||||
|
||||
// this.args.disableRequests !== 'true' && capture_requests(this, this.page);
|
||||
// this.args.disableResponses !== 'true' && capture_requests(this, this.page);
|
||||
// capture_responses(this, this.page);
|
||||
const page2 = this.page as any;
|
||||
//page2.setCacheEnabled(false);
|
||||
/*
|
||||
await page2._client.send('Security.setOverrideCertificateErrors', {
|
||||
override: true
|
||||
});
|
||||
*/
|
||||
await page2._client.on('Security.certificateError', (event: any) => {
|
||||
page2._client.send('Security.handleCertificateError', {
|
||||
eventId: event.eventId,
|
||||
action: 'continue' // ignore error and continue request
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const getScope = (cliArgs?: any) => {
|
||||
if (!instance) {
|
||||
instance = new Scope();
|
||||
instance.args = cliArgs;
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
25
packages/cad/src/renderer/puppeteer/constants.ts
Normal file
25
packages/cad/src/renderer/puppeteer/constants.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { NavigationOptions } from 'puppeteer';
|
||||
export const defaultTenant = 1;
|
||||
export const userSessionsTab = (base: string) => `${base}/e/${defaultTenant}/#usersearchoverview;gtf=l_2_HOURS`;
|
||||
export const loginUrl = (base: string) => `${base}/login`;
|
||||
export const loginUrlDemoDev = () => `https://proxy-dev.dynatracelabs.com/sso/ProxyLocator.jsp`;
|
||||
export const defaultPageOptions = (): NavigationOptions => {
|
||||
return {
|
||||
timeout: 5000,
|
||||
waitUntil: 'networkidle2'
|
||||
}
|
||||
}
|
||||
|
||||
export const replay_api_overview = 'uemshareddetails/rumoverviewdata/usersearchoverview';
|
||||
const ts = () => {
|
||||
const d = new Date();
|
||||
return d.getHours() + '_' + d.getMinutes() + '_' + d.getSeconds();
|
||||
}
|
||||
export const sessionName = (url?: string) => `Pupeteer :${ts()}`;
|
||||
|
||||
export const maxSessionWaitingTime = 1000 * 60 * 3;
|
||||
export const responseRetryTime = 1000 * 8;
|
||||
export const defaultMutationRoot = '#mutationsRoot';
|
||||
export const defaultMutationTag = 'div';
|
||||
export const defaultHeavyMutations = 2000;
|
||||
export const defaultMediumMutations = 500;
|
||||
186
packages/cad/src/renderer/puppeteer/index.ts
Normal file
186
packages/cad/src/renderer/puppeteer/index.ts
Normal file
@ -0,0 +1,186 @@
|
||||
import { launch, Page } from 'puppeteer'
|
||||
import { readFileSync } from 'fs';
|
||||
import * as moment from 'moment';
|
||||
import { sync as unlink } from '@plastichub/fs/remove';
|
||||
import { async as iterator } from '@plastichub/fs/iterator';
|
||||
import {
|
||||
debug, inspect,
|
||||
Options, TraceEntry, TraceTiming,
|
||||
default_trace_path,
|
||||
ReportEntry,
|
||||
NetworkReportEntry,
|
||||
sizeToString,
|
||||
log,
|
||||
spinner,
|
||||
STATS_SUFFIX,
|
||||
TRACE_SUFFIX
|
||||
} from '../../';
|
||||
import { end_time } from './times';
|
||||
import { find_time } from './trace';
|
||||
import { rl } from './stdin';
|
||||
import { report, find_report, get_report } from './report';
|
||||
import { IProcessingNode } from '@plastichub/fs/interfaces';
|
||||
|
||||
const included_categories = ['devtools.timeline'];
|
||||
|
||||
export class Puppeteer {
|
||||
|
||||
static clean(url: string, options: Options) {
|
||||
iterator(options.cwd, {
|
||||
matching: [`*${STATS_SUFFIX}`, `*${TRACE_SUFFIX}`]
|
||||
}).then((it) => {
|
||||
let node: IProcessingNode = null;
|
||||
while (node = it.next()) {
|
||||
unlink(node.path);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
static async begin(url: string, options: Options) {
|
||||
|
||||
const browser = await launch({
|
||||
headless: options.headless,
|
||||
devtools: false
|
||||
});
|
||||
return await browser.newPage();
|
||||
}
|
||||
static async crawler(url: string, options?: Options) {
|
||||
|
||||
const page = await this.begin(url, options);
|
||||
|
||||
}
|
||||
static async repl(url: string, options?: Options) {
|
||||
|
||||
const page = await this.begin(url, options);
|
||||
page.on('console', msg => inspect('Console Message:', msg.text()));
|
||||
|
||||
await page.goto(url, {
|
||||
timeout: 600000,
|
||||
waitUntil: 'networkidle0'
|
||||
});
|
||||
|
||||
const readline = rl(`${url}#`, (line: string) => {
|
||||
page.evaluate(line).then((results) => {
|
||||
inspect(`Did evaluate ${line} to `, results);
|
||||
})
|
||||
}, () => this.end(page));
|
||||
}
|
||||
|
||||
|
||||
static async end(page: Page) {
|
||||
|
||||
const browser = await page.browser();
|
||||
await page.close();
|
||||
await browser.close();
|
||||
}
|
||||
|
||||
static async summary(url: string, options?: Options) {
|
||||
|
||||
const browser = await launch({
|
||||
headless: options.headless,
|
||||
devtools: true
|
||||
});
|
||||
const page = await browser.newPage();
|
||||
await page.goto(url, {
|
||||
timeout: 600000,
|
||||
waitUntil: 'networkidle0'
|
||||
});
|
||||
const metrics = await page.metrics();
|
||||
await this.end(page);
|
||||
return metrics;
|
||||
}
|
||||
|
||||
static async detail(url: string, options?: Options) {
|
||||
|
||||
const network_stats = report();
|
||||
const ReceivedTotal = get_report(network_stats, 'Received Total');
|
||||
const ReceivedStyleSheets = get_report(network_stats, 'Received Stylesheets');
|
||||
const ReceivedScripts = get_report(network_stats, 'Received Scripts');
|
||||
const ReceivedHTML = get_report(network_stats, 'Received HTML');
|
||||
const ReceivedImages = get_report(network_stats, 'Received Images');
|
||||
const ReceivedJSON = get_report(network_stats, 'Received JSON');
|
||||
const ReceivedFonts = get_report(network_stats, 'Received Fonts');
|
||||
const ReceivedBinary = get_report(network_stats, 'Received Binary');
|
||||
const MimeMap = {
|
||||
'application/javascript': ReceivedScripts,
|
||||
'text/javascript': ReceivedScripts,
|
||||
'text/css': ReceivedStyleSheets,
|
||||
'text/html': ReceivedHTML,
|
||||
'image/png': ReceivedImages,
|
||||
'image/gif': ReceivedImages,
|
||||
'image/svg+xml': ReceivedImages,
|
||||
'application/json': ReceivedJSON,
|
||||
'application/octet-stream': ReceivedBinary,
|
||||
'font/woff2': ReceivedFonts,
|
||||
'application/font-woff2': ReceivedFonts
|
||||
}
|
||||
|
||||
const traceFile = default_trace_path(options.cwd, url);
|
||||
|
||||
const page = await this.begin(url, options);
|
||||
await page.tracing.start({
|
||||
path: traceFile,
|
||||
categories: included_categories
|
||||
});
|
||||
await page.goto(url, {
|
||||
timeout: 600000,
|
||||
waitUntil: 'networkidle0'
|
||||
});
|
||||
const metrics = await (page as any)._client.send('Performance.getMetrics');
|
||||
const nowTs = new Date().getTime();
|
||||
// const navigationStart = getTimeFromMetrics(metrics, 'NavigationStart');
|
||||
const navigationStart = find_time(metrics, 'Timestamp') + nowTs;
|
||||
await page.tracing.stop();
|
||||
|
||||
// --- extracting data from trace.json ---
|
||||
const tracing = JSON.parse(readFileSync(traceFile, 'utf8'));
|
||||
|
||||
const dataReceivedEvents = tracing.traceEvents.filter(x => x.name === 'ResourceReceivedData');
|
||||
const dataResponseEvents = tracing.traceEvents.filter(x => x.name === 'ResourceReceiveResponse');
|
||||
|
||||
// find resource in responses or return default empty
|
||||
const content_response = (requestId: string): TraceEntry => dataResponseEvents.find((x) =>
|
||||
x.args.data.requestId === requestId)
|
||||
|| { args: { data: { encodedDataLength: 0 } } };
|
||||
|
||||
const report_per_mime = (mime: string): NetworkReportEntry => MimeMap[mime] || get_report(network_stats, mime);
|
||||
|
||||
// our iteration over the trace
|
||||
// @TODO: convert to a better tree structure to avoid O(n) lookups
|
||||
// @TODO: emit to extensions: events & aspects
|
||||
// @TODO: calculate times
|
||||
// @TODO: filter
|
||||
// @TODO: options.mask
|
||||
// @TODO: this iterator might get async
|
||||
ReceivedTotal.value = dataReceivedEvents.reduce((first, x) => {
|
||||
const content = content_response(x.args.data.requestId);
|
||||
const data = content.args.data;
|
||||
const report = report_per_mime(data.mimeType);
|
||||
if (data.fromCache === false) {
|
||||
report.value += x.args.data.encodedDataLength
|
||||
report.count++;
|
||||
} else {
|
||||
report.cached_count++;
|
||||
}
|
||||
ReceivedTotal.count++;
|
||||
return first + x.args.data.encodedDataLength;
|
||||
}, ReceivedTotal.value);
|
||||
|
||||
// calulate finals
|
||||
[ReceivedTotal, ReceivedHTML, ReceivedImages, ReceivedJSON,
|
||||
ReceivedScripts, ReceivedFonts, ReceivedBinary
|
||||
].forEach((r) => r.formatted = sizeToString(r.value))
|
||||
|
||||
// --- end extracting data from trace.json ---
|
||||
|
||||
let results = [];
|
||||
|
||||
// lights off
|
||||
await this.end(page);
|
||||
|
||||
return {
|
||||
times: [],
|
||||
network: network_stats
|
||||
}
|
||||
}
|
||||
}
|
||||
176
packages/cad/src/renderer/puppeteer/network.ts
Normal file
176
packages/cad/src/renderer/puppeteer/network.ts
Normal file
@ -0,0 +1,176 @@
|
||||
import { Page, Request, Response } from 'puppeteer';
|
||||
import { sessionName, maxSessionWaitingTime, defaultPageOptions, userSessionsTab } from './constants';
|
||||
import * as debug from '../../log';
|
||||
import { Scope } from './Scope';
|
||||
import { parse } from 'url';
|
||||
import { navigateToUserSessions } from './processes';
|
||||
|
||||
const debugRequests = true;
|
||||
const debugResponses = false;
|
||||
export const default_postdata = (request: Request): any => request.postData && request.postData() || {};
|
||||
export type ResponseMatch = (request: any) => boolean;
|
||||
export const HasUserSessions = (request: Request) => (default_postdata(request).users)
|
||||
export const MyUserSessions = (url: string, request: Request) => SessionWithName(request, sessionName(url));
|
||||
export const SessionWithName = (request: Request, name: string) => {
|
||||
const data = default_postdata(request).users || [];
|
||||
return data.find((user: any) => user.id === name)
|
||||
}
|
||||
export type ResponseResolve = Response & {
|
||||
data: any;
|
||||
}
|
||||
const default_prepare = (requests: Request[]): Request[] => {
|
||||
return requests;
|
||||
};
|
||||
|
||||
const default_filter_json = (r: Request) => ((r.headers()['content-type'] || '').startsWith('application/json;')) === true;
|
||||
const responses = async function (requests: Request[]) { return Promise.all(requests.map(r => r.response()!.json())) };
|
||||
|
||||
export const findRequest = (url: string, requests: Request[], match?: ResponseMatch): Request[] => {
|
||||
url = decodeURIComponent(url);
|
||||
if (!match) {
|
||||
return requests.filter((request) => request.url().indexOf(url) !== -1);
|
||||
} else {
|
||||
const results = requests.filter((request) => request.url().indexOf(url) !== -1);
|
||||
return results.filter((r) => match!(r));
|
||||
}
|
||||
}
|
||||
|
||||
export function waitForResponse(url: string, scope: Scope, match: ResponseMatch, timeout: number = 5000): Promise<any[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
try {
|
||||
|
||||
let requests = default_prepare(scope.requests).filter(default_filter_json).filter(r => r.response() != null);
|
||||
requests = requests.filter((request) => request.url().indexOf(url) !== -1);
|
||||
responses(requests).then((responses) => {
|
||||
const ret = responses.filter(match);
|
||||
if (ret.length) {
|
||||
resolve(ret);
|
||||
} else {
|
||||
reject('cant find anything yet');
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
debug.error('waitForResponse Error ', error);
|
||||
}
|
||||
}, timeout);
|
||||
})
|
||||
}
|
||||
export function waitForResponseNTimes(url: string, scope: Scope, match: ResponseMatch, timeout: number = 5000) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const maxTime = maxSessionWaitingTime;
|
||||
const retryTime = 8000;
|
||||
let reachedTimeOut = false;
|
||||
let interval: any = null;
|
||||
interval = setInterval(() => {
|
||||
if (reachedTimeOut) {
|
||||
clearInterval(interval);
|
||||
debug.error('reached max');
|
||||
reject('reached maximum timeout');
|
||||
return;
|
||||
}
|
||||
onReload(scope).then(() => {
|
||||
scope.page.reload().then(() => {
|
||||
debug.info('retry ');
|
||||
waitForResponse(url, scope, match, retryTime).then((session) => {
|
||||
debug.inspect('got my session', session);
|
||||
clearInterval(interval);
|
||||
resolve(session);
|
||||
}).catch((e) => {
|
||||
debug.error('found nothing');
|
||||
})
|
||||
}).catch((e) => {
|
||||
console.error('error loading page : ', e);
|
||||
});
|
||||
});
|
||||
}, retryTime);
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
reachedTimeOut = true;
|
||||
clearInterval(interval);
|
||||
reject('max timeout reached');
|
||||
}, maxTime);
|
||||
});
|
||||
};
|
||||
|
||||
export async function capture_request(where: any[], request: Request) {
|
||||
debugRequests && debug.inspect('Request', { url: request.url(), data: request.postData() });
|
||||
where.push({ url: request.url(), data: await request.postData(), request: request });
|
||||
debugRequests && debug.inspect('requests', where.map(r => r.url));
|
||||
}
|
||||
|
||||
export async function capture_response(where: any[], response: Response) {
|
||||
debugResponses && debug.inspect('Response', { url: response.url(), data: await response.json() });
|
||||
where.push(response);
|
||||
}
|
||||
|
||||
export async function capture_requests(scope: Scope, page: Page) {
|
||||
|
||||
await page.setRequestInterception(true);
|
||||
|
||||
scope.requests = [];
|
||||
page.on('request', (interceptedRequest: Request) => {
|
||||
|
||||
if(scope.onRequest){
|
||||
scope.onRequest(interceptedRequest, scope);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const url = decodeURIComponent(interceptedRequest.url());
|
||||
const parsed = parse(url, true);
|
||||
if (url.includes('.css') || url.includes('.svg')) {
|
||||
interceptedRequest.abort();
|
||||
return;
|
||||
|
||||
}
|
||||
const query = parsed.query;
|
||||
const isJson = (interceptedRequest.headers()['content-type'] || '').startsWith('application/json') === true;
|
||||
if (isJson) {
|
||||
// capture_request(scope.requests, interceptedRequest);
|
||||
//debugRequests && debug.inspect('q ' + query['contentType'] + ' ' + url);
|
||||
}
|
||||
interceptedRequest.continue();
|
||||
} catch (e) {
|
||||
debug.error('error parsing request ', e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function capture_responses(scope: Scope, page: Page) {
|
||||
try {
|
||||
// await page.setRequestInterception(true);
|
||||
} catch (e) {
|
||||
debug.error('error intercepting responses', e);
|
||||
}
|
||||
scope.responses = [];
|
||||
page.on('response', response => {
|
||||
try {
|
||||
const isJson = (response.headers()['content-type'] || '').startsWith('application/json;') === true;
|
||||
const url = response.url();
|
||||
|
||||
if (response.status() === 200) {
|
||||
if (isJson) {
|
||||
capture_response(scope.responses, response);
|
||||
}
|
||||
if (scope.onResponse) {
|
||||
scope.onResponse(response, scope);
|
||||
}
|
||||
} else {
|
||||
debugResponses && debug.error(`Error loading ${url} : ${response.status()}`);
|
||||
}
|
||||
} catch (e) {
|
||||
debugResponses && debug.error('Error parsing response');
|
||||
}
|
||||
});
|
||||
}
|
||||
export async function onReload(scope: Scope) {
|
||||
scope.requests = [];
|
||||
try {
|
||||
await scope.page.setRequestInterception(false);
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
await scope.page.setRequestInterception(true);
|
||||
}
|
||||
0
packages/cad/src/renderer/puppeteer/page.ts
Normal file
0
packages/cad/src/renderer/puppeteer/page.ts
Normal file
78
packages/cad/src/renderer/puppeteer/processes.ts
Normal file
78
packages/cad/src/renderer/puppeteer/processes.ts
Normal file
@ -0,0 +1,78 @@
|
||||
import { Page, Request } from 'puppeteer';
|
||||
import { Options } from './types';
|
||||
import { loginUrl, defaultPageOptions, userSessionsTab, loginUrlDemoDev } from './constants';
|
||||
|
||||
export async function loginFrontEnd(page: Page, options: Options) {
|
||||
// await page.goto(loginUrl(options.dynatraceUrl), defaultPageOptions());
|
||||
await page.type('#user', 'admin');
|
||||
await page.type('#password', 'admin');
|
||||
await page.click('#login-form > .maindiv > .logindiv > .submitdiv > .button');
|
||||
await page.waitForSelector('.tenant-selector');
|
||||
await page.click('.textboxdiv > .tenant-selector:nth-child(2)');
|
||||
}
|
||||
|
||||
export async function loginDemoDev(page: Page, options: Options) {
|
||||
await page.goto(loginUrlDemoDev(), defaultPageOptions());
|
||||
await page.type('#IDToken1', 'guenter.baumgart@ruxit.com');
|
||||
await page.click('.maindiv > .logindiv > form > div > #formsubmit');
|
||||
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve(1);
|
||||
console.log('time out');
|
||||
}, 20 * 1000)
|
||||
});
|
||||
|
||||
console.log('logged in 1/2!');
|
||||
|
||||
|
||||
/*
|
||||
const puppeteer = require('puppeteer');
|
||||
|
||||
(async () => {
|
||||
const browser = await puppeteer.launch()
|
||||
const page = await browser.newPage()
|
||||
|
||||
await page.waitForSelector('.logindiv > form > .textboxdiv > .emailLoginIcon > #IDToken1')
|
||||
await page.click('.logindiv > form > .textboxdiv > .emailLoginIcon > #IDToken1')
|
||||
|
||||
await page.waitForSelector('.maindiv > .logindiv > form > div > #formsubmit')
|
||||
await page.click('.maindiv > .logindiv > form > div > #formsubmit')
|
||||
|
||||
const navigationPromise = page.waitForNavigation()
|
||||
await navigationPromise
|
||||
|
||||
await page.waitForSelector('.logindiv > form > .margin-bottom\3A > .passwordIcon > #IDToken2')
|
||||
await page.click('.logindiv > form > .margin-bottom\3A > .passwordIcon > #IDToken2')
|
||||
|
||||
await page.waitForSelector('.logindiv > form > fieldset > div > #IDToken3')
|
||||
await page.click('.logindiv > form > fieldset > div > #IDToken3')
|
||||
|
||||
await page.waitForSelector('form > fieldset > #button-base > div > #loginButton_0')
|
||||
await page.click('form > fieldset > #button-base > div > #loginButton_0')
|
||||
|
||||
await navigationPromise
|
||||
|
||||
await navigationPromise
|
||||
|
||||
await navigationPromise
|
||||
|
||||
await browser.close()
|
||||
})()
|
||||
*/
|
||||
|
||||
//await page.type('#password', 'admin');
|
||||
//await page.click('#login-form > .maindiv > .logindiv > .submitdiv > .button');
|
||||
//await page.waitForSelector('.tenant-selector');
|
||||
//await page.click('.textboxdiv > .tenant-selector:nth-child(2)');
|
||||
}
|
||||
|
||||
export async function navigateToUserSessions(page: Page, options: Options) {
|
||||
// await page.goto(userSessionsTab(options.dynatraceUrl), defaultPageOptions());
|
||||
}
|
||||
|
||||
|
||||
export async function navigateToUserLocalhost(page: Page, options?: Options) {
|
||||
// await page.goto('http://localhost/', defaultPageOptions());
|
||||
}
|
||||
|
||||
40
packages/cad/src/renderer/puppeteer/report.ts
Normal file
40
packages/cad/src/renderer/puppeteer/report.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { NetworkReportEntry } from './types';
|
||||
const report_item = (name: string): NetworkReportEntry => {
|
||||
return {
|
||||
name: name,
|
||||
value: 0,
|
||||
formatted: '',
|
||||
count: 0,
|
||||
cached_count: 0,
|
||||
external_count: 0,
|
||||
local_count: 0,
|
||||
times: {
|
||||
end: 0,
|
||||
formatted: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const report = () => {
|
||||
return [
|
||||
report_item('Received Total'),
|
||||
report_item('Received Stylesheets'),
|
||||
report_item('Received Scripts'),
|
||||
report_item('Received HTML'),
|
||||
report_item('Received JSON'),
|
||||
report_item('Received Images'),
|
||||
report_item('Received Fonts'),
|
||||
report_item('Received Binary')
|
||||
]
|
||||
}
|
||||
|
||||
export const find_report = (where: any[], name: string) => where.find((media) => media.name === name);
|
||||
|
||||
export const get_report = (where: any[], type: string) => {
|
||||
let record = find_report(where, type);
|
||||
if (!record) {
|
||||
record = report_item(type);
|
||||
where.push(record);
|
||||
}
|
||||
return record;
|
||||
}
|
||||
31
packages/cad/src/renderer/puppeteer/stdin.ts
Normal file
31
packages/cad/src/renderer/puppeteer/stdin.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { createInterface, ReadLine } from 'readline';
|
||||
import { Page } from 'puppeteer';
|
||||
import chalk from 'chalk';
|
||||
|
||||
|
||||
|
||||
export const rl = (prompt: string, onLine?: (line: string) => void, onClose?: () => {}) => {
|
||||
const rl = createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
prompt: chalk.green(prompt)
|
||||
})
|
||||
console.log('start stdin: ' + prompt);
|
||||
rl.prompt()
|
||||
rl.on('line', (line) => {
|
||||
if(!line){
|
||||
return;
|
||||
}
|
||||
try {
|
||||
onLine(line);
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
rl.prompt()
|
||||
}
|
||||
})
|
||||
rl.on('close', () => {
|
||||
rl.close()
|
||||
onClose();
|
||||
});
|
||||
return rl;
|
||||
}
|
||||
12
packages/cad/src/renderer/puppeteer/times.ts
Normal file
12
packages/cad/src/renderer/puppeteer/times.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { TraceEntry } from './types'
|
||||
export const end_time = (entry: TraceEntry): number => {
|
||||
const timing = entry.args.data.timing;
|
||||
const start = timing.requestTime;
|
||||
const received = entry.ts;
|
||||
//it might be more accurate to calc this with the header times
|
||||
const headersReceived = start + timing.receiveHeadersEnd / 1000;
|
||||
let responseReceived = headersReceived;
|
||||
responseReceived = Math.min(responseReceived, headersReceived);
|
||||
responseReceived = Math.max(responseReceived, start);
|
||||
return Math.max(-1, responseReceived);
|
||||
}
|
||||
57
packages/cad/src/renderer/puppeteer/trace.ts
Normal file
57
packages/cad/src/renderer/puppeteer/trace.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import { NetworkReportEntry, TraceEntry } from "./types";
|
||||
|
||||
export const find_time = (metrics, name) =>
|
||||
metrics.metrics.find(x => x.name === name).value;
|
||||
|
||||
export const all_with_name = (where: NetworkReportEntry[], name: string) =>
|
||||
where.filter((entry) => entry.name === name);
|
||||
|
||||
/*
|
||||
export const tree = (entries: TraceEntry[]) => {
|
||||
const tasks = [];
|
||||
let currentTask;
|
||||
|
||||
for (const event of entries) {
|
||||
// Only look at X (Complete), B (Begin), and E (End) events as they have most data
|
||||
if (event.ph !== 'X' && event.ph !== 'B' && event.ph !== 'E') continue;
|
||||
|
||||
// Update currentTask based on the elapsed time.
|
||||
// The next event may be after currentTask has ended.
|
||||
while (
|
||||
currentTask &&
|
||||
Number.isFinite(currentTask.endTime) &&
|
||||
currentTask.endTime <= event.ts
|
||||
) {
|
||||
currentTask = currentTask.parent;
|
||||
}
|
||||
|
||||
if (!currentTask) {
|
||||
// We can't start a task with an end event
|
||||
if (event.ph === 'E') {
|
||||
throw new Error('Fatal trace logic error');
|
||||
}
|
||||
|
||||
currentTask = entries._createNewTaskNode(event);
|
||||
tasks.push(currentTask);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (event.ph === 'X' || event.ph === 'B') {
|
||||
// We're starting a nested event, create it as a child and make it the currentTask
|
||||
const newTask = entries._createNewTaskNode(event, currentTask);
|
||||
tasks.push(newTask);
|
||||
currentTask = newTask;
|
||||
} else {
|
||||
if (currentTask.event.ph !== 'B') {
|
||||
throw new Error('Fatal trace logic error');
|
||||
}
|
||||
|
||||
// We're ending an event, update the end time and the currentTask to its parent
|
||||
currentTask.endTime = event.ts;
|
||||
currentTask = currentTask.parent;
|
||||
}
|
||||
}
|
||||
return tasks;
|
||||
}
|
||||
*/
|
||||
124
packages/cad/src/renderer/puppeteer/types.ts
Normal file
124
packages/cad/src/renderer/puppeteer/types.ts
Normal file
@ -0,0 +1,124 @@
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
// Application types
|
||||
//
|
||||
export enum OutputTarget {
|
||||
STDOUT = 'console',
|
||||
FILE = 'file'
|
||||
}
|
||||
|
||||
export enum OutputFormat {
|
||||
text = 'text',
|
||||
json = 'json'
|
||||
}
|
||||
|
||||
export interface Options {
|
||||
// @TODO: support many
|
||||
url?: string;
|
||||
format?: OutputFormat;
|
||||
// @TODO: support many
|
||||
target?: OutputTarget;
|
||||
headless?: boolean;
|
||||
// output path
|
||||
path?: string;
|
||||
// @TODO: required to pick profile/config files
|
||||
cwd?: string;
|
||||
// @TODO: time of sesssion, mapped to Puppeteer waitUntil, if it's a number, the session will be opened for that
|
||||
// time window, time=-1 means infinity, useful for repl. sessions
|
||||
time?: number;
|
||||
// @TODO: reload interval
|
||||
reload?: number;
|
||||
// @TODO: repl. --repl=true=interactive or repl=path to specify script
|
||||
repl?: string | boolean;
|
||||
// TODO: colored ouput
|
||||
colors?: boolean;
|
||||
}
|
||||
|
||||
// options for certain categories as network, rendering,...
|
||||
export interface OptionEx {
|
||||
include?: string | string[];
|
||||
exclude?: string | string[];
|
||||
query?: string | string[];
|
||||
}
|
||||
|
||||
export type OptionsEx = Options & {
|
||||
launchOptions?: {
|
||||
// puppeteer launch options
|
||||
}
|
||||
waitOptions?: {
|
||||
// puppeteer wait options: wait for selector,...
|
||||
}
|
||||
replOptions?: {
|
||||
script?: string;
|
||||
}
|
||||
}
|
||||
|
||||
export type OutputResult = boolean;
|
||||
|
||||
export interface ReportEntry {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export type NetworkReportEntry = ReportEntry & {
|
||||
value: number;
|
||||
formatted: string;
|
||||
count: number;
|
||||
cached_count: number;
|
||||
external_count: number;
|
||||
local_count: number;
|
||||
times?: {
|
||||
end: number,
|
||||
formatted: string;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
// Foreign data types (trace data)
|
||||
//
|
||||
|
||||
// type for a network resource's timing
|
||||
export interface TraceTiming {
|
||||
requestTime: number;
|
||||
proxyStart: number;
|
||||
proxyEnd: number;
|
||||
dnsStart: number;
|
||||
dnsEnd: number;
|
||||
connectStart: number;
|
||||
connectEnd: number;
|
||||
sslStart: number;
|
||||
sslEnd: number;
|
||||
workerStart: number;
|
||||
workerReady: number;
|
||||
sendStart: number;
|
||||
sendEnd: number;
|
||||
receiveHeadersEnd: number;
|
||||
pushStart: number;
|
||||
pushEnd: number;
|
||||
}
|
||||
|
||||
export interface TraceData {
|
||||
requestId: string;
|
||||
frame: string;
|
||||
statusCode: number;
|
||||
mimeType: string;
|
||||
encodedDataLength: number;
|
||||
fromCache: boolean;
|
||||
fromServiceWorker: boolean;
|
||||
timing: TraceTiming;
|
||||
}
|
||||
export interface TraceArgs {
|
||||
data: TraceData;
|
||||
}
|
||||
|
||||
export interface TraceEntry {
|
||||
pid: number;
|
||||
tid: number;
|
||||
ts: number;
|
||||
ph: string; // B: begin, | E: end; For async events: S: start, F: finish
|
||||
cat: string;
|
||||
name: string;
|
||||
args: TraceArgs;
|
||||
tts: number;
|
||||
s: string;
|
||||
}
|
||||
54
packages/cad/src/report/csv.ts
Normal file
54
packages/cad/src/report/csv.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import * as path from 'path';
|
||||
const csv = require('csv-stringify/lib/sync');
|
||||
const OSR_REGEX = /^[0-9].+$/;
|
||||
const isOSR = (filename) => filename.match(OSR_REGEX) != null;
|
||||
|
||||
export const reportCSV = (data) => {
|
||||
|
||||
const image = (path) => `)})`;
|
||||
const file = (path) => `[${path}](./${(encodeURI(path))})`;
|
||||
|
||||
const qty = (filename) => {
|
||||
if (isOSR(filename)) {
|
||||
const parts = filename.split("_");
|
||||
const partsLength = parts.length;
|
||||
const token = parts[partsLength - 3];
|
||||
if (token) {
|
||||
return parseInt(token.replace('x', ''));
|
||||
}
|
||||
}
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
const thickness = (filename) => {
|
||||
if (isOSR(filename)) {
|
||||
const parts = filename.split("_");
|
||||
const partsLength = parts.length;
|
||||
const token = parts[partsLength - 2];
|
||||
if (token) {
|
||||
return token;
|
||||
}
|
||||
}
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
const set = data.map((d) => [
|
||||
`${path.parse(d.target).name}`,
|
||||
`${image(path.parse(d.target).name + path.parse(d.target).ext)}`,
|
||||
`${file(path.parse(d.src).name + path.parse(d.src).ext)}`,
|
||||
`${qty(path.parse(d.src).name)}`,
|
||||
`${thickness(path.parse(d.src).name)}`,
|
||||
`${isOSR(path.parse(d.src).name) ? 'Laser' : 'Unkown'}`,
|
||||
''
|
||||
]
|
||||
);
|
||||
|
||||
const csvString = csv(set, {
|
||||
header: true,
|
||||
delimiter: ',',
|
||||
columns: { 'a': 'Name', 'b': 'Thumbnail', 'c': 'File', 'd': 'Qty', 'f': 'Thickness', 'g': 'Type', 'h': 'Missing' }
|
||||
});
|
||||
|
||||
return csvString;
|
||||
|
||||
}
|
||||
1
packages/cad/src/report/index.ts
Normal file
1
packages/cad/src/report/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { reportCSV } from './csv'
|
||||
218
packages/cad/src/slic3r_argv.ts
Normal file
218
packages/cad/src/slic3r_argv.ts
Normal file
@ -0,0 +1,218 @@
|
||||
import * as CLI from 'yargs'
|
||||
import * as path from 'path'
|
||||
|
||||
import {
|
||||
SolidworkOptions,
|
||||
SlicerOptions,
|
||||
logger
|
||||
} from './'
|
||||
|
||||
import { pathInfo, resolve } from "@plastichub/osr-commons"
|
||||
import { sync as read } from "@plastichub/fs/read"
|
||||
import { sync as exists } from "@plastichub/fs/exists"
|
||||
|
||||
import { substitute } from './'
|
||||
|
||||
export const defaultOptions = (yargs: CLI.Argv) => {
|
||||
return yargs.option('src', {
|
||||
default: './',
|
||||
describe: 'The source directory or source file. Glob patters are supported!',
|
||||
demandOption: true
|
||||
}).option('dst', {
|
||||
describe: 'Destination folder or file'
|
||||
}).option('Report', {
|
||||
describe: 'Optional conversion report. Can be JSON, HTML, CSV or Markdown'
|
||||
}).option('debug', {
|
||||
default: false,
|
||||
describe: 'Enable internal debug messages',
|
||||
type: 'boolean'
|
||||
}).option('alt', {
|
||||
default: false,
|
||||
describe: 'Use alternate tokenizer, & instead of $',
|
||||
type: 'boolean'
|
||||
}).option('skip', {
|
||||
default: true,
|
||||
describe: 'Skip existing files',
|
||||
type: 'boolean'
|
||||
}).option('dry', {
|
||||
default: false,
|
||||
describe: 'Run without conversion',
|
||||
type: 'boolean'
|
||||
}).option('verbose', {
|
||||
default: true,
|
||||
describe: 'Show internal messages',
|
||||
type: 'boolean'
|
||||
}).option('saveArgs', {
|
||||
describe: 'Save command line options to a file',
|
||||
type: 'string'
|
||||
}).option('saveAsProfile', {
|
||||
describe: 'Save command line options to a json file. To be loaded via --profile=file.json',
|
||||
type: 'string'
|
||||
}).option('profile', {
|
||||
describe: 'Load options from a json file',
|
||||
type: 'string'
|
||||
}).option('log', {
|
||||
describe: 'Save Slic3r output to a file',
|
||||
type: 'string'
|
||||
})
|
||||
}
|
||||
|
||||
// Sanitizes faulty user argv options for all commands.
|
||||
export const sanitizeSingle = (argv: CLI.Arguments): SolidworkOptions => {
|
||||
|
||||
const src = path.resolve('' + argv.src);
|
||||
const config: any = argv.config ? read(path.resolve('' + argv.config), 'json') : {};
|
||||
const extraVariables = {};
|
||||
for (const key in config) {
|
||||
if (Object.prototype.hasOwnProperty.call(config, key)) {
|
||||
const element = config[key];
|
||||
if (typeof element === 'string') {
|
||||
extraVariables[key] = element;
|
||||
}
|
||||
}
|
||||
}
|
||||
const args: any = {
|
||||
src: src,
|
||||
dst: '' + argv.dst as string,
|
||||
report: argv.report ? path.resolve(argv.report as string) : null,
|
||||
debug: argv.debug,
|
||||
verbose: argv.verbose,
|
||||
dry: argv.dry,
|
||||
cache: argv.skip,
|
||||
alt: argv.alt,
|
||||
// glob: argv.glob as string,
|
||||
variables: { ...extraVariables },
|
||||
args: argv.args || ''
|
||||
} as any
|
||||
|
||||
if (!args.src) {
|
||||
logger.error('Invalid source, abort');
|
||||
return process.exit()
|
||||
}
|
||||
|
||||
args.srcInfo = pathInfo(argv.src as string);
|
||||
|
||||
if (!args.srcInfo.FILES) {
|
||||
logger.error(`Invalid source files, abort`);
|
||||
return process.exit()
|
||||
}
|
||||
|
||||
for (const key in args.srcInfo) {
|
||||
if (Object.prototype.hasOwnProperty.call(args.srcInfo, key)) {
|
||||
args.variables['SRC_' + key] = args.srcInfo[key]
|
||||
}
|
||||
}
|
||||
|
||||
if (argv.dst) {
|
||||
args.dst = path.resolve(args.dst)
|
||||
args.dstInfo = pathInfo(args.dst as string)
|
||||
args.dstInfo.PATH = path.resolve(argv.dst as string)
|
||||
|
||||
for (const key in args.dstInfo) {
|
||||
if (Object.prototype.hasOwnProperty.call(args.dstInfo, key)) {
|
||||
args.variables['DST_' + key] = args.dstInfo[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
return args as any
|
||||
}
|
||||
|
||||
export const sanitize = (argv: any): SlicerOptions => {
|
||||
const src = path.resolve('' + argv.src)
|
||||
const config: any = argv.config ? read(path.resolve('' + argv.config), 'json') : {}
|
||||
const extraVariables = {};
|
||||
for (const key in config) {
|
||||
if (Object.prototype.hasOwnProperty.call(config, key)) {
|
||||
const element = config[key];
|
||||
if (typeof element === 'string') {
|
||||
extraVariables[key] = element;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let args = {
|
||||
src: src,
|
||||
dst: '' + argv.dst as string,
|
||||
report: argv.report,
|
||||
debug: argv.debug,
|
||||
verbose: argv.verbose,
|
||||
dry: argv.dry,
|
||||
onNode: argv.onNode,
|
||||
cache: argv.skip,
|
||||
alt: argv.alt,
|
||||
variables: {
|
||||
...extraVariables
|
||||
},
|
||||
...argv
|
||||
} as SlicerOptions
|
||||
|
||||
|
||||
args.extruderOffset = args.extruderOffset ? args.extruderOffset : { x: 0, y: 0 }
|
||||
|
||||
|
||||
if (!args.src) {
|
||||
logger.error('Invalid source, abort')
|
||||
return
|
||||
}
|
||||
|
||||
args.srcInfo = pathInfo(argv.src as string)
|
||||
|
||||
if (!args.srcInfo.FILES) {
|
||||
logger.error(`Invalid source files, abort`, args.srcInfo)
|
||||
return process.exit()
|
||||
}
|
||||
|
||||
for (const key in args.srcInfo) {
|
||||
if (Object.prototype.hasOwnProperty.call(args.srcInfo, key)) {
|
||||
args.variables['SRC_' + key] = args.srcInfo[key]
|
||||
}
|
||||
}
|
||||
|
||||
if (argv.saveAsProfile) {
|
||||
args.saveAsProfile = path.resolve(resolve(args.saveAsProfile, args.alt, args.variables))
|
||||
}
|
||||
|
||||
if (argv.saveArgs) {
|
||||
args.saveArgs = path.resolve(resolve(args.saveArgs, args.alt, args.variables))
|
||||
}
|
||||
|
||||
if (argv.report) {
|
||||
args.report = path.resolve(resolve(args.report, args.alt, args.variables))
|
||||
}
|
||||
|
||||
if (argv.profile) {
|
||||
args.profile = path.resolve(resolve(args.profile, args.alt, args.variables))
|
||||
}
|
||||
|
||||
if (argv.dst) {
|
||||
args.dst = path.resolve(resolve(args.dst, args.alt, args.variables))
|
||||
args.dstInfo = pathInfo(args.dst as string)
|
||||
args.dstInfo.PATH = argv.dst as string
|
||||
|
||||
for (const key in args.dstInfo) {
|
||||
if (Object.prototype.hasOwnProperty.call(args.dstInfo, key)) {
|
||||
args.variables['DST_' + key] = args.dstInfo[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (argv.profile) {
|
||||
args.profile = path.resolve(resolve(args.profile, args.alt, args.variables))
|
||||
if (exists(args.profile)) {
|
||||
const profile = read(args.profile, 'json') as SlicerOptions
|
||||
if (profile) {
|
||||
args = {
|
||||
...args,
|
||||
...profile
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (argv.log) {
|
||||
args.log = path.resolve(substitute(args.alt, args.log, args.variables))
|
||||
}
|
||||
|
||||
return args
|
||||
}
|
||||
|
||||
265
packages/cad/src/sw_argv.ts
Normal file
265
packages/cad/src/sw_argv.ts
Normal file
@ -0,0 +1,265 @@
|
||||
import * as CLI from 'yargs'
|
||||
import * as path from 'path'
|
||||
|
||||
import { substitute } from "@plastichub/core/strings"
|
||||
import { resolve, forward_slash, pathInfo } from "@plastichub/osr-commons"
|
||||
import { sync as read } from "@plastichub/fs/read"
|
||||
|
||||
import { SolidworkOptions, logger } from './'
|
||||
import { DEFAULT_REPORT } from './constants'
|
||||
|
||||
export const defaultOptions = (yargs: CLI.Argv) => {
|
||||
return yargs.option('src', {
|
||||
default: './',
|
||||
describe: 'The source directory or source file. Glob patters are supported!',
|
||||
demandOption: true
|
||||
}).option('format', {
|
||||
describe: 'The target format. Multiple formats are allowed as well, use --format=pdf --format=jpg'
|
||||
}).option('dst', {
|
||||
describe: 'Destination folder or file'
|
||||
}).option('view', {
|
||||
default: 'Render',
|
||||
describe: 'Sets the target view'
|
||||
}).option('Report', {
|
||||
describe: 'Optional conversion report. Can be JSON, HTML, CSV or Markdown'
|
||||
}).option('debug', {
|
||||
default: false,
|
||||
describe: 'Enable internal debug messages',
|
||||
type: 'boolean'
|
||||
}).option('alt', {
|
||||
default: false,
|
||||
describe: 'Use alternate tokenizer, & instead of $',
|
||||
type: 'boolean'
|
||||
}).option('report', {
|
||||
default: DEFAULT_REPORT,
|
||||
describe: '',
|
||||
type: 'string'
|
||||
}).option('configuration', {
|
||||
default: 'Default',
|
||||
describe: 'Set the Model Configuration to be used',
|
||||
type: 'string',
|
||||
alias: 'c'
|
||||
}).option('cache', {
|
||||
default: false,
|
||||
describe: 'Enable caching',
|
||||
type: 'boolean'
|
||||
}).option('hidden', {
|
||||
describe: 'Hide Solidworks window',
|
||||
type: 'string'
|
||||
}).option('dry', {
|
||||
default: false,
|
||||
describe: 'Run without conversion',
|
||||
type: 'boolean'
|
||||
}).option('verbose', {
|
||||
default: true,
|
||||
describe: 'Show internal messages',
|
||||
type: 'boolean'
|
||||
}).option('quality', {
|
||||
default: 2,
|
||||
describe: 'Raytrace quality',
|
||||
type: 'number'
|
||||
}).option('renderer', {
|
||||
default: 'Solidworks',
|
||||
describe: 'Renderer to be used: Solidworks or Photoview',
|
||||
type: 'string',
|
||||
}).option('sw', {
|
||||
describe: 'Set explicit the path to the Solidworks binaries & scripts.\
|
||||
Otherwise, set it to 2020, 2022 or 2023 to use the built-in binaries',
|
||||
default: 2024,
|
||||
type: 'number'
|
||||
}).option('swv', {
|
||||
describe: 'Internal Solidworks Version. Use \'30\' for 2022',
|
||||
default: 32,
|
||||
type: 'number'
|
||||
}).option('pack', {
|
||||
describe: 'Pack and Go an Assembly. The destination must be a folder',
|
||||
default: false,
|
||||
type: 'boolean'
|
||||
}).option('rebuild', {
|
||||
describe: 'Rebuild the assembly',
|
||||
default: false,
|
||||
type: 'boolean'
|
||||
}).option('save', {
|
||||
describe: 'Save the assembly or part',
|
||||
default: false,
|
||||
type: 'boolean'
|
||||
}).option('light', {
|
||||
describe: 'Open assembly in light mode',
|
||||
default: false,
|
||||
type: 'boolean'
|
||||
}).option('script', {
|
||||
describe: 'Set explicit the path to the Solidworks script',
|
||||
default: 'convert.exe'
|
||||
}).option('bom-config', {
|
||||
describe: 'Set the Model Configuration to be used',
|
||||
default: 'Default'
|
||||
}).option('bom-template', {
|
||||
describe: 'Path to the BOM template. Default is osr-cad/sw/bom-all.sldbomtbt'
|
||||
}).option('bom-type', {
|
||||
describe: 'Bom Type : default = 2 - PartsOnly = 1 | TopLevelOnly = 2 | Indented = 3',
|
||||
type: "number",
|
||||
default: 2
|
||||
}).option('bom-detail', {
|
||||
describe: 'Bom Numbering : default = 1 - Type_None = 0 | Type_Detailed = 1 | Type_Flat = 2 | BOMNotSet = 3',
|
||||
type: "number",
|
||||
default: 1
|
||||
}).option('bom-images', {
|
||||
describe: 'Add an image in the first colum',
|
||||
type: 'boolean',
|
||||
default: false
|
||||
})
|
||||
}
|
||||
|
||||
export const sanitizeSingle = (argv: CLI.Arguments): SolidworkOptions => {
|
||||
|
||||
const src = forward_slash(path.resolve(resolve(argv.src as string)))
|
||||
const config: any = argv.config ? read(path.resolve('' + argv.config), 'json') : {}
|
||||
const extraVariables = {}
|
||||
for (const key in config) {
|
||||
if (Object.prototype.hasOwnProperty.call(config, key)) {
|
||||
const element = config[key]
|
||||
if (typeof element === 'string') {
|
||||
extraVariables[key] = element
|
||||
}
|
||||
}
|
||||
}
|
||||
const args: SolidworkOptions = {
|
||||
src: src,
|
||||
dst: '' + argv.dst as string,
|
||||
debug: argv.debug,
|
||||
verbose: argv.verbose,
|
||||
dry: argv.dry,
|
||||
cache: argv.cache,
|
||||
alt: argv.alt,
|
||||
quality: argv.quality,
|
||||
clear: argv.clear,
|
||||
renderer: argv.renderer || "solidworks",
|
||||
close: argv.close,
|
||||
width: argv.width || "1024",
|
||||
height: argv.height || "1024",
|
||||
hidden: argv.hidden || "true",
|
||||
configuration: argv.configuration || 'Default',
|
||||
script: argv.script || 'convert.exe',
|
||||
sw: argv.sw || 2024,
|
||||
swv: argv.swv || 32,
|
||||
view: argv.view || '*Render',
|
||||
pack: argv.pack,
|
||||
light: argv.light,
|
||||
rebuild: argv.rebuild,
|
||||
save: argv.save,
|
||||
write: argv.write,
|
||||
variables: { ...extraVariables },
|
||||
report: argv.report || DEFAULT_REPORT,
|
||||
args: argv.args || ''
|
||||
} as SolidworkOptions
|
||||
|
||||
if (!args.src) {
|
||||
logger.error('Invalid source, abort')
|
||||
return process.exit()
|
||||
}
|
||||
args.srcInfo = pathInfo(argv.src as string)
|
||||
if (!args.srcInfo.FILES) {
|
||||
logger.error(`Invalid source files, abort`);
|
||||
return process.exit()
|
||||
}
|
||||
|
||||
for (const key in args.srcInfo) {
|
||||
if (Object.prototype.hasOwnProperty.call(args.srcInfo, key)) {
|
||||
args.variables['SRC_' + key] = args.srcInfo[key]
|
||||
}
|
||||
}
|
||||
|
||||
if (argv.dst) {
|
||||
args.dst = path.resolve(args.dst)
|
||||
args.dstInfo = pathInfo(args.dst as string)
|
||||
args.dstInfo.PATH = path.resolve(argv.dst as string)
|
||||
|
||||
for (const key in args.dstInfo) {
|
||||
if (Object.prototype.hasOwnProperty.call(args.dstInfo, key)) {
|
||||
args.variables['DST_' + key] = args.dstInfo[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
export const sanitize = (argv: any): SolidworkOptions => {
|
||||
const src = forward_slash(path.resolve(resolve(argv.src)))
|
||||
const config: any = argv.config ? read(path.resolve('' + argv.config), 'json') : {}
|
||||
const extraVariables = {}
|
||||
for (const key in config) {
|
||||
if (Object.prototype.hasOwnProperty.call(config, key)) {
|
||||
const element = config[key];
|
||||
if (typeof element === 'string') {
|
||||
extraVariables[key] = element
|
||||
}
|
||||
}
|
||||
}
|
||||
const args: SolidworkOptions = {
|
||||
src: src,
|
||||
dst: '' + argv.dst as string,
|
||||
debug: argv.debug,
|
||||
verbose: argv.verbose,
|
||||
dry: argv.dry,
|
||||
onNode: argv.onNode,
|
||||
cache: argv.cache,
|
||||
hidden: argv.hidden || "true",
|
||||
renderer: argv.renderer || "solidworks",
|
||||
alt: argv.alt,
|
||||
quality: argv.quality,
|
||||
logLevel: argv.logLevel,
|
||||
close: argv.close,
|
||||
width: argv.width || "1024",
|
||||
height: argv.height || "1024",
|
||||
script: argv.script || 'convert.exe',
|
||||
sw: argv.sw || 2024,
|
||||
swv: argv.swv || 32,
|
||||
configuration: argv.configuration || 'Default',
|
||||
report: argv.report || DEFAULT_REPORT,
|
||||
pack: argv.pack,
|
||||
light: argv.light,
|
||||
rebuild: argv.rebuild,
|
||||
save: argv.save,
|
||||
write: argv.write,
|
||||
variables: { ...extraVariables },
|
||||
view: argv.view || 'Render',
|
||||
args: argv.args || '',
|
||||
"bom-config": argv['bom-config'],
|
||||
"bom-detail": argv['bom-detail'],
|
||||
"bom-template": argv['bom-template'],
|
||||
"bom-type": argv['bom-type'],
|
||||
"bom-images": argv['bom-images'],
|
||||
} as SolidworkOptions
|
||||
|
||||
if (!args.src) {
|
||||
logger.error('Invalid source, abort')
|
||||
return process.exit()
|
||||
}
|
||||
|
||||
args.srcInfo = pathInfo(src)
|
||||
|
||||
if (!args.srcInfo.FILES) {
|
||||
logger.error(`Invalid source files, abort`, args.srcInfo)
|
||||
return process.exit()
|
||||
}
|
||||
|
||||
for (const key in args.srcInfo) {
|
||||
if (Object.prototype.hasOwnProperty.call(args.srcInfo, key)) {
|
||||
args.variables['SRC_' + key] = args.srcInfo[key]
|
||||
}
|
||||
}
|
||||
|
||||
if (argv.dst) {
|
||||
args.dst = path.resolve(substitute(args.dst, args.variables))
|
||||
args.dstInfo = pathInfo(args.dst as string)
|
||||
args.dstInfo.PATH = argv.dst as string
|
||||
for (const key in args.dstInfo) {
|
||||
if (Object.prototype.hasOwnProperty.call(args.dstInfo, key)) {
|
||||
args.variables['DST_' + key] = args.dstInfo[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
(args as SolidworkOptions).view = argv.view as string || "Render"
|
||||
return args
|
||||
}
|
||||
|
||||
48
packages/cad/src/tree.cs
Normal file
48
packages/cad/src/tree.cs
Normal file
@ -0,0 +1,48 @@
|
||||
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using SolidWorks.Interop.sldworks;
|
||||
using SolidWorks.Interop.swconst;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class TreeItem
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public List<TreeItem> Children { get; set; }
|
||||
}
|
||||
|
||||
public string CreateAssemblyTreeJson(string filePath)
|
||||
{
|
||||
SldWorks swApp = new SldWorks();
|
||||
ModelDoc2 swModel = swApp.OpenDoc6(filePath, (int)swDocumentTypes_e.swDocASSEMBLY, (int)swOpenDocOptions_e.swOpenDocOptions_Silent, "", 0, 0);
|
||||
AssemblyDoc swAssembly = (AssemblyDoc)swModel;
|
||||
|
||||
TreeItem root = new TreeItem();
|
||||
root.Name = swModel.GetTitle();
|
||||
|
||||
List<TreeItem> children = new List<TreeItem>();
|
||||
TraverseComponents(swAssembly.GetComponents(false), children);
|
||||
root.Children = children;
|
||||
|
||||
swApp.CloseDoc(swModel.GetTitle());
|
||||
|
||||
return JsonConvert.SerializeObject(root);
|
||||
}
|
||||
|
||||
private void TraverseComponents(Component2[] components, List<TreeItem> parentList)
|
||||
{
|
||||
foreach (Component2 component in components)
|
||||
{
|
||||
TreeItem item = new TreeItem();
|
||||
item.Name = component.Name2;
|
||||
|
||||
if (component.GetChildrenCount() > 0)
|
||||
{
|
||||
List<TreeItem> children = new List<TreeItem>();
|
||||
TraverseComponents(component.GetChildren(), children);
|
||||
item.Children = children;
|
||||
}
|
||||
|
||||
parentList.Add(item);
|
||||
}
|
||||
}
|
||||
228
packages/cad/src/types.ts
Normal file
228
packages/cad/src/types.ts
Normal file
@ -0,0 +1,228 @@
|
||||
import { PATH_INFO } from "@plastichub/osr-commons"
|
||||
|
||||
export interface IOptionsCache {
|
||||
cache?: boolean
|
||||
clear?: boolean
|
||||
}
|
||||
export interface IOptionsBase extends IOptionsCache {
|
||||
src: string
|
||||
srcInfo?: PATH_INFO
|
||||
dstInfo?: PATH_INFO
|
||||
dst?: string
|
||||
alt?: boolean
|
||||
debug?: boolean
|
||||
verbose?: boolean
|
||||
dry?: boolean
|
||||
report?: string
|
||||
variables: Record<string, string>
|
||||
script?: string
|
||||
args?: string
|
||||
onNode: (data:INodeCallback) => Promise<void>
|
||||
}
|
||||
export interface INodeCallback {
|
||||
src: string
|
||||
target: string
|
||||
options: IOptionsBase
|
||||
}
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Solidworks
|
||||
export interface IBomOptions {
|
||||
'bom-template'?: string
|
||||
'bom-detail'?: number
|
||||
'bom-type'?: number
|
||||
'bom-images'?: boolean
|
||||
'bom-config'?: string
|
||||
}
|
||||
export interface SolidworkOptions extends IOptionsBase, IBomOptions {
|
||||
close?: boolean
|
||||
configuration?: string
|
||||
height?: number
|
||||
hidden?: string
|
||||
light?: boolean
|
||||
logLevel?: string
|
||||
pack?: boolean
|
||||
quality?: number
|
||||
rebuild?: boolean
|
||||
renderer?: string
|
||||
save?: boolean
|
||||
sw?: string
|
||||
swv?: number
|
||||
view?: string
|
||||
width?: number
|
||||
write?: boolean
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Slic3r
|
||||
|
||||
export interface IPrintCenter {
|
||||
x: number
|
||||
y: number
|
||||
}
|
||||
|
||||
export type EGCodeFlavor = 'reprap' | 'marlin' | 'teacup' | 'makerware' | 'sailfish' | 'mach3' | 'noextrusion'
|
||||
|
||||
export interface IBedSize {
|
||||
width: number
|
||||
height: number
|
||||
}
|
||||
|
||||
export interface IExtruderOffset {
|
||||
x: number
|
||||
y: number
|
||||
}
|
||||
|
||||
export type TOutputResult = boolean
|
||||
|
||||
export interface ISlic3rCLIOptions {
|
||||
avoidCrossingPerimeters?: boolean
|
||||
bedSize?: IBedSize
|
||||
bedTemperature?: number
|
||||
bottomSolidLayers?: number
|
||||
bridgeAcceleration?: number
|
||||
bridgeFanSpeed?: number
|
||||
bridgeFlowRatio?: number
|
||||
bridgeSpeed?: number
|
||||
brimWidth?: number
|
||||
completeObjects?: boolean
|
||||
cooling?: boolean
|
||||
cut?: number
|
||||
defaultAcceleration?: number
|
||||
disableFanFirstLayers?: number
|
||||
dontSupportBridges?: boolean
|
||||
duplicate?: number
|
||||
duplicateDistance?: number
|
||||
duplicateGrid?: string
|
||||
endGCode?: boolean
|
||||
endGcode?: boolean
|
||||
exportSvg?: boolean
|
||||
externalPerimeterExtrusionWidth?: number | string
|
||||
externalPerimetersFirst?: boolean
|
||||
externalPerimeterSpeed?: number
|
||||
extraPerimeters?: boolean
|
||||
extruderClearanceHeight?: number
|
||||
extruderClearanceRadius?: number
|
||||
extruderOffset?: IExtruderOffset
|
||||
extrusionMultiplier?: number
|
||||
extrusionWidth?: number | string
|
||||
fanAlwaysOn?: boolean
|
||||
fanBelowLayerTime?: number
|
||||
filamentDiameter?: number
|
||||
fillAngle?: number
|
||||
fillDensity?: number
|
||||
fillPattern?: string
|
||||
firstLayerAcceleration?: number
|
||||
firstLayerBedTemperature?: number
|
||||
firstLayerExtrusionWidth?: number | string
|
||||
firstLayerHeight?: number
|
||||
firstLayerSpeed?: number
|
||||
firstLayerTemperature?: number
|
||||
g0?: boolean
|
||||
gapFillSpeed?: number
|
||||
GCodeArcs?: boolean
|
||||
GCodeComments?: boolean
|
||||
GCodeFlavor?: EGCodeFlavor
|
||||
infillAcceleration?: number
|
||||
infillEveryLayers?: number
|
||||
infillExtruder?: number
|
||||
infillExtrusionWidth?: number | string
|
||||
infillFirst?: boolean
|
||||
infillOnlyWhereNeeded?: boolean
|
||||
infillSpeed?: number
|
||||
info?: boolean
|
||||
inputFile?: string
|
||||
layerGCode?: boolean
|
||||
layerGcode?: boolean
|
||||
layerHeight?: number
|
||||
load?: string
|
||||
log?: string
|
||||
maxFanSpeed?: number
|
||||
merge?: boolean
|
||||
minFanSpeed?: number
|
||||
minPrintSpeed?: number
|
||||
minSkirtLength?: number
|
||||
notes?: string
|
||||
nozzleDiameter?: number
|
||||
onlyRetractWhenCrossingPerimeters?: boolean
|
||||
oozePrevention?: boolean
|
||||
outputDirectory?: string
|
||||
outputFile?: string
|
||||
outputFilenameFormat?: string
|
||||
overhangs?: boolean
|
||||
perimeterAcceleration?: number
|
||||
perimeterExtruder?: number
|
||||
perimeterExtrusionWidth?: number | string
|
||||
perimeters?: number
|
||||
perimeterSpeed?: number
|
||||
postProcess?: string[]
|
||||
postProcessScripts?: string[]
|
||||
pressureAdvance?: number
|
||||
printCenter?: IPrintCenter
|
||||
profile?: string
|
||||
raftLayers?: number
|
||||
repair?: boolean
|
||||
resolution?: number
|
||||
retractBeforeTravel?: number
|
||||
retractLayerChange?: boolean
|
||||
retractLength?: number
|
||||
retractLengthToolchange?: number
|
||||
retractLift?: number
|
||||
retractRestartExtra?: number
|
||||
retractRestartExtraToolchange?: number
|
||||
retractSpeed?: number
|
||||
rotate?: number
|
||||
save?: string
|
||||
saveArgs?: string
|
||||
saveAsProfile?: string
|
||||
scale?: number
|
||||
seamPosition?: 'random' | 'nearest' | 'aligned'
|
||||
skirtDistance?: number
|
||||
skirtHeight?: number
|
||||
skirts?: number
|
||||
slowdownBelowLayerTime?: number
|
||||
smallPerimeterSpeed?: number
|
||||
solidFillPattern?: string
|
||||
solidInfillBelowArea?: number
|
||||
solidInfillEveryLayers?: number
|
||||
solidInfillExtruder?: number
|
||||
solidInfillExtrusionWidth?: number | string
|
||||
solidInfillSpeed?: number
|
||||
solidLayers?: boolean
|
||||
spiralVase?: boolean
|
||||
split?: boolean
|
||||
standbyTemperatureDelta?: number
|
||||
startGCode?: boolean
|
||||
startGcode?: boolean
|
||||
supportMaterial?: boolean
|
||||
supportMaterialAngle?: number
|
||||
supportMaterialEnforceLayers?: number
|
||||
supportMaterialExtruder?: number
|
||||
supportMaterialExtrusionWidth?: number | string
|
||||
supportMaterialInterfaceExtruder?: number
|
||||
supportMaterialInterfaceLayers?: number
|
||||
supportMaterialInterfaceSpacing?: number
|
||||
supportMaterialInterfaceSpeed?: number
|
||||
supportMaterialPattern?: string
|
||||
supportMaterialSpacing?: number
|
||||
supportMaterialSpeed?: number
|
||||
supportMaterialThreshold?: number
|
||||
temperature?: number
|
||||
thinWalls?: boolean
|
||||
threads?: number
|
||||
toolchangeGCode?: boolean
|
||||
toolchangeGcode?: boolean
|
||||
topInfillExtrusionWidth?: number | string
|
||||
topSolidInfillSpeed?: number
|
||||
topSolidLayers?: number
|
||||
travelSpeed?: number
|
||||
useFirmwareRetraction?: boolean
|
||||
useRelativeEDistances?: boolean
|
||||
useVolumetricE?: boolean
|
||||
vibrationLimit?: number
|
||||
wipe?: boolean
|
||||
zOffset?: number
|
||||
}
|
||||
|
||||
export type SlicerOptions = IOptionsBase & ISlic3rCLIOptions
|
||||
BIN
packages/cad/sw/2020/CommandLine.dll
Normal file
BIN
packages/cad/sw/2020/CommandLine.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/ExportHTML.exe
Normal file
BIN
packages/cad/sw/2020/ExportHTML.exe
Normal file
Binary file not shown.
26
packages/cad/sw/2020/ExportHTML.xml
Normal file
26
packages/cad/sw/2020/ExportHTML.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>
|
||||
ExportHTML
|
||||
</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:ExportHTML.My.Resources.Resources">
|
||||
<summary>
|
||||
A strongly-typed resource class, for looking up localized strings, etc.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ExportHTML.My.Resources.Resources.ResourceManager">
|
||||
<summary>
|
||||
Returns the cached ResourceManager instance used by this class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ExportHTML.My.Resources.Resources.Culture">
|
||||
<summary>
|
||||
Overrides the current thread's CurrentUICulture property for all
|
||||
resource lookups using this strongly typed resource class.
|
||||
</summary>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
BIN
packages/cad/sw/2020/Jering.Javascript.NodeJS.dll
Normal file
BIN
packages/cad/sw/2020/Jering.Javascript.NodeJS.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
packages/cad/sw/2020/Microsoft.AspNetCore.Http.Abstractions.dll
Normal file
BIN
packages/cad/sw/2020/Microsoft.AspNetCore.Http.Abstractions.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/Microsoft.AspNetCore.Http.Features.dll
Normal file
BIN
packages/cad/sw/2020/Microsoft.AspNetCore.Http.Features.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
packages/cad/sw/2020/Microsoft.Extensions.Http.dll
Normal file
BIN
packages/cad/sw/2020/Microsoft.Extensions.Http.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
packages/cad/sw/2020/Microsoft.Extensions.Logging.dll
Normal file
BIN
packages/cad/sw/2020/Microsoft.Extensions.Logging.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/Microsoft.Extensions.Options.dll
Normal file
BIN
packages/cad/sw/2020/Microsoft.Extensions.Options.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/Microsoft.Extensions.Primitives.dll
Normal file
BIN
packages/cad/sw/2020/Microsoft.Extensions.Primitives.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/Newtonsoft.Json.dll
Normal file
BIN
packages/cad/sw/2020/Newtonsoft.Json.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/SolidWorks.Interop.sldworks.dll
Normal file
BIN
packages/cad/sw/2020/SolidWorks.Interop.sldworks.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/SolidWorks.Interop.swconst.dll
Normal file
BIN
packages/cad/sw/2020/SolidWorks.Interop.swconst.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/SolidWorks.Interop.swpublished.dll
Normal file
BIN
packages/cad/sw/2020/SolidWorks.Interop.swpublished.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/System.Diagnostics.DiagnosticSource.dll
Normal file
BIN
packages/cad/sw/2020/System.Diagnostics.DiagnosticSource.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/System.Runtime.CompilerServices.Unsafe.dll
Normal file
BIN
packages/cad/sw/2020/System.Runtime.CompilerServices.Unsafe.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/System.Text.Encodings.Web.dll
Normal file
BIN
packages/cad/sw/2020/System.Text.Encodings.Web.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/System.Text.Json.dll
Normal file
BIN
packages/cad/sw/2020/System.Text.Json.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/Xarial.XCad.SolidWorks.dll
Normal file
BIN
packages/cad/sw/2020/Xarial.XCad.SolidWorks.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/Xarial.XCad.Toolkit.dll
Normal file
BIN
packages/cad/sw/2020/Xarial.XCad.Toolkit.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/Xarial.XCad.dll
Normal file
BIN
packages/cad/sw/2020/Xarial.XCad.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/bom-all.sldbomtbt
Normal file
BIN
packages/cad/sw/2020/bom-all.sldbomtbt
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/bom-default.sldbomtbt
Normal file
BIN
packages/cad/sw/2020/bom-default.sldbomtbt
Normal file
Binary file not shown.
481
packages/cad/sw/2020/bom.deps.json
Normal file
481
packages/cad/sw/2020/bom.deps.json
Normal file
@ -0,0 +1,481 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v3.1",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v3.1": {
|
||||
"bom/1.0.0": {
|
||||
"dependencies": {
|
||||
"CommandLineParser": "2.8.0",
|
||||
"Jering.Javascript.NodeJS": "6.0.1",
|
||||
"Newtonsoft.Json": "13.0.1",
|
||||
"Xarial.XCad.SolidWorks": "0.7.4"
|
||||
},
|
||||
"runtime": {
|
||||
"bom.dll": {}
|
||||
}
|
||||
},
|
||||
"CommandLineParser/2.8.0": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/CommandLine.dll": {
|
||||
"assemblyVersion": "2.8.0.0",
|
||||
"fileVersion": "2.8.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Jering.Javascript.NodeJS/6.0.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Hosting.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.DependencyInjection": "5.0.1",
|
||||
"Microsoft.Extensions.Http": "5.0.0",
|
||||
"Microsoft.Extensions.Logging": "5.0.0",
|
||||
"Microsoft.Extensions.Options": "5.0.0",
|
||||
"System.Text.Encodings.Web": "5.0.1",
|
||||
"System.Text.Json": "5.0.2"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netcoreapp3.1/Jering.Javascript.NodeJS.dll": {
|
||||
"assemblyVersion": "1.0.0.0",
|
||||
"fileVersion": "1.0.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.AspNetCore.Hosting.Abstractions/2.2.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Hosting.Server.Abstractions": "2.2.0",
|
||||
"Microsoft.AspNetCore.Http.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Hosting.Abstractions": "2.2.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Microsoft.AspNetCore.Hosting.Abstractions.dll": {
|
||||
"assemblyVersion": "2.2.0.0",
|
||||
"fileVersion": "2.2.0.18316"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.AspNetCore.Hosting.Server.Abstractions/2.2.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Http.Features": "2.2.0",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "2.2.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Microsoft.AspNetCore.Hosting.Server.Abstractions.dll": {
|
||||
"assemblyVersion": "2.2.0.0",
|
||||
"fileVersion": "2.2.0.18316"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.AspNetCore.Http.Abstractions/2.2.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Http.Features": "2.2.0",
|
||||
"System.Text.Encodings.Web": "5.0.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Microsoft.AspNetCore.Http.Abstractions.dll": {
|
||||
"assemblyVersion": "2.2.0.0",
|
||||
"fileVersion": "2.2.0.18316"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.AspNetCore.Http.Features/2.2.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Microsoft.AspNetCore.Http.Features.dll": {
|
||||
"assemblyVersion": "2.2.0.0",
|
||||
"fileVersion": "2.2.0.18316"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions/2.2.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Microsoft.Extensions.Configuration.Abstractions.dll": {
|
||||
"assemblyVersion": "2.2.0.0",
|
||||
"fileVersion": "2.2.0.18315"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection/5.0.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.dll": {
|
||||
"assemblyVersion": "5.0.0.1",
|
||||
"fileVersion": "5.0.120.57516"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
|
||||
"assemblyVersion": "5.0.0.0",
|
||||
"fileVersion": "5.0.20.51904"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.FileProviders.Abstractions/2.2.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Microsoft.Extensions.FileProviders.Abstractions.dll": {
|
||||
"assemblyVersion": "2.2.0.0",
|
||||
"fileVersion": "2.2.0.18315"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Hosting.Abstractions/2.2.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Microsoft.Extensions.Hosting.Abstractions.dll": {
|
||||
"assemblyVersion": "2.2.0.0",
|
||||
"fileVersion": "2.2.0.18316"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Http/5.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0",
|
||||
"Microsoft.Extensions.Logging": "5.0.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "5.0.0",
|
||||
"Microsoft.Extensions.Options": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Microsoft.Extensions.Http.dll": {
|
||||
"assemblyVersion": "5.0.0.0",
|
||||
"fileVersion": "5.0.20.51904"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging/5.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "5.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "5.0.0",
|
||||
"Microsoft.Extensions.Options": "5.0.0",
|
||||
"System.Diagnostics.DiagnosticSource": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.1/Microsoft.Extensions.Logging.dll": {
|
||||
"assemblyVersion": "5.0.0.0",
|
||||
"fileVersion": "5.0.20.51904"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions/5.0.0": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.dll": {
|
||||
"assemblyVersion": "5.0.0.0",
|
||||
"fileVersion": "5.0.20.51904"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Options/5.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0",
|
||||
"Microsoft.Extensions.Primitives": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Microsoft.Extensions.Options.dll": {
|
||||
"assemblyVersion": "5.0.0.0",
|
||||
"fileVersion": "5.0.20.51904"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives/5.0.0": {
|
||||
"runtime": {
|
||||
"lib/netcoreapp3.0/Microsoft.Extensions.Primitives.dll": {
|
||||
"assemblyVersion": "5.0.0.0",
|
||||
"fileVersion": "5.0.20.51904"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Newtonsoft.Json/13.0.1": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Newtonsoft.Json.dll": {
|
||||
"assemblyVersion": "13.0.0.0",
|
||||
"fileVersion": "13.0.1.25517"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.DiagnosticSource/5.0.0": {
|
||||
"runtime": {
|
||||
"lib/netstandard1.3/System.Diagnostics.DiagnosticSource.dll": {
|
||||
"assemblyVersion": "5.0.0.0",
|
||||
"fileVersion": "5.0.20.51904"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe/5.0.0": {
|
||||
"runtime": {
|
||||
"lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.dll": {
|
||||
"assemblyVersion": "5.0.0.0",
|
||||
"fileVersion": "5.0.20.51904"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Text.Encodings.Web/5.0.1": {
|
||||
"runtime": {
|
||||
"lib/netcoreapp3.0/System.Text.Encodings.Web.dll": {
|
||||
"assemblyVersion": "5.0.0.1",
|
||||
"fileVersion": "5.0.421.11614"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Text.Json/5.0.2": {
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "5.0.0",
|
||||
"System.Text.Encodings.Web": "5.0.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netcoreapp3.0/System.Text.Json.dll": {
|
||||
"assemblyVersion": "5.0.0.0",
|
||||
"fileVersion": "5.0.521.16609"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Xarial.XCad/0.7.4": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.1/Xarial.XCad.dll": {
|
||||
"assemblyVersion": "0.7.4.0",
|
||||
"fileVersion": "0.7.4.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Xarial.XCad.SolidWorks/0.7.4": {
|
||||
"dependencies": {
|
||||
"Xarial.XCad": "0.7.4",
|
||||
"Xarial.XCad.SolidWorks.Interops": "0.3.0",
|
||||
"Xarial.XCad.Toolkit": "0.7.4"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netcoreapp3.1/Xarial.XCad.SolidWorks.dll": {
|
||||
"assemblyVersion": "0.7.4.0",
|
||||
"fileVersion": "0.7.4.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Xarial.XCad.SolidWorks.Interops/0.3.0": {
|
||||
"runtime": {
|
||||
"lib/net40/SolidWorks.Interop.sldworks.dll": {
|
||||
"assemblyVersion": "28.1.0.74",
|
||||
"fileVersion": "28.1.0.74"
|
||||
},
|
||||
"lib/net40/SolidWorks.Interop.swconst.dll": {
|
||||
"assemblyVersion": "28.1.0.74",
|
||||
"fileVersion": "28.1.0.74"
|
||||
},
|
||||
"lib/net40/SolidWorks.Interop.swpublished.dll": {
|
||||
"assemblyVersion": "28.1.0.74",
|
||||
"fileVersion": "28.1.0.74"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Xarial.XCad.Toolkit/0.7.4": {
|
||||
"dependencies": {
|
||||
"Xarial.XCad": "0.7.4"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.1/Xarial.XCad.Toolkit.dll": {
|
||||
"assemblyVersion": "0.7.4.0",
|
||||
"fileVersion": "0.7.4.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"bom/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"CommandLineParser/2.8.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-eco2HlKQBY4Joz9odHigzGpVzv6pjsXnY5lziioMveQxr+i2Z7xYcIOMeZTgYiqnMtMAbXMXsVhrNfWO5vJS8Q==",
|
||||
"path": "commandlineparser/2.8.0",
|
||||
"hashPath": "commandlineparser.2.8.0.nupkg.sha512"
|
||||
},
|
||||
"Jering.Javascript.NodeJS/6.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Dg0YRu0EtyWwLM7hrp6jJg5kQE0LIr44bu7XQzyaSWQfb8Nfzvcv/SduQOu1fz/52SCKZp2H873QClO0SUjJzg==",
|
||||
"path": "jering.javascript.nodejs/6.0.1",
|
||||
"hashPath": "jering.javascript.nodejs.6.0.1.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.AspNetCore.Hosting.Abstractions/2.2.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-ubycklv+ZY7Kutdwuy1W4upWcZ6VFR8WUXU7l7B2+mvbDBBPAcfpi+E+Y5GFe+Q157YfA3C49D2GCjAZc7Mobw==",
|
||||
"path": "microsoft.aspnetcore.hosting.abstractions/2.2.0",
|
||||
"hashPath": "microsoft.aspnetcore.hosting.abstractions.2.2.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.AspNetCore.Hosting.Server.Abstractions/2.2.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-1PMijw8RMtuQF60SsD/JlKtVfvh4NORAhF4wjysdABhlhTrYmtgssqyncR0Stq5vqtjplZcj6kbT4LRTglt9IQ==",
|
||||
"path": "microsoft.aspnetcore.hosting.server.abstractions/2.2.0",
|
||||
"hashPath": "microsoft.aspnetcore.hosting.server.abstractions.2.2.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.AspNetCore.Http.Abstractions/2.2.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Nxs7Z1q3f1STfLYKJSVXCs1iBl+Ya6E8o4Oy1bCxJ/rNI44E/0f6tbsrVqAWfB7jlnJfyaAtIalBVxPKUPQb4Q==",
|
||||
"path": "microsoft.aspnetcore.http.abstractions/2.2.0",
|
||||
"hashPath": "microsoft.aspnetcore.http.abstractions.2.2.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.AspNetCore.Http.Features/2.2.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-ziFz5zH8f33En4dX81LW84I6XrYXKf9jg6aM39cM+LffN9KJahViKZ61dGMSO2gd3e+qe5yBRwsesvyqlZaSMg==",
|
||||
"path": "microsoft.aspnetcore.http.features/2.2.0",
|
||||
"hashPath": "microsoft.aspnetcore.http.features.2.2.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions/2.2.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==",
|
||||
"path": "microsoft.extensions.configuration.abstractions/2.2.0",
|
||||
"hashPath": "microsoft.extensions.configuration.abstractions.2.2.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection/5.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-//mDNrYeiJ0eh/awFhDFJQzkRVra/njU5Y4fyK7X29g5HScrzbUkKOKlyTtygthcGFt4zNC8G5CFCjb/oizomA==",
|
||||
"path": "microsoft.extensions.dependencyinjection/5.0.1",
|
||||
"hashPath": "microsoft.extensions.dependencyinjection.5.0.1.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-ORj7Zh81gC69TyvmcUm9tSzytcy8AVousi+IVRAI8nLieQjOFryRusSFh7+aLk16FN9pQNqJAiMd7BTKINK0kA==",
|
||||
"path": "microsoft.extensions.dependencyinjection.abstractions/5.0.0",
|
||||
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.FileProviders.Abstractions/2.2.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-EcnaSsPTqx2MGnHrmWOD0ugbuuqVT8iICqSqPzi45V5/MA1LjUNb0kwgcxBGqizV1R+WeBK7/Gw25Jzkyk9bIw==",
|
||||
"path": "microsoft.extensions.fileproviders.abstractions/2.2.0",
|
||||
"hashPath": "microsoft.extensions.fileproviders.abstractions.2.2.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Hosting.Abstractions/2.2.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-+k4AEn68HOJat5gj1TWa6X28WlirNQO9sPIIeQbia+91n03esEtMSSoekSTpMjUzjqtJWQN3McVx0GvSPFHF/Q==",
|
||||
"path": "microsoft.extensions.hosting.abstractions/2.2.0",
|
||||
"hashPath": "microsoft.extensions.hosting.abstractions.2.2.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Http/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-kT1ijDKZuSUhBtYoC1sXrmVKP7mA08h9Xrsr4VrS/QOtiKCEtUTTd7dd3XI9dwAb46tZSak13q/zdIcr4jqbyg==",
|
||||
"path": "microsoft.extensions.http/5.0.0",
|
||||
"hashPath": "microsoft.extensions.http.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Logging/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-MgOwK6tPzB6YNH21wssJcw/2MKwee8b2gI7SllYfn6rvTpIrVvVS5HAjSU2vqSku1fwqRvWP0MdIi14qjd93Aw==",
|
||||
"path": "microsoft.extensions.logging/5.0.0",
|
||||
"hashPath": "microsoft.extensions.logging.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-NxP6ahFcBnnSfwNBi2KH2Oz8Xl5Sm2krjId/jRR3I7teFphwiUoUeZPwTNA21EX+5PtjqmyAvKaOeBXcJjcH/w==",
|
||||
"path": "microsoft.extensions.logging.abstractions/5.0.0",
|
||||
"hashPath": "microsoft.extensions.logging.abstractions.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Options/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-CBvR92TCJ5uBIdd9/HzDSrxYak+0W/3+yxrNg8Qm6Bmrkh5L+nu6m3WeazQehcZ5q1/6dDA7J5YdQjim0165zg==",
|
||||
"path": "microsoft.extensions.options/5.0.0",
|
||||
"hashPath": "microsoft.extensions.options.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Primitives/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-cI/VWn9G1fghXrNDagX9nYaaB/nokkZn0HYAawGaELQrl8InSezfe9OnfPZLcJq3esXxygh3hkq2c3qoV3SDyQ==",
|
||||
"path": "microsoft.extensions.primitives/5.0.0",
|
||||
"hashPath": "microsoft.extensions.primitives.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"Newtonsoft.Json/13.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==",
|
||||
"path": "newtonsoft.json/13.0.1",
|
||||
"hashPath": "newtonsoft.json.13.0.1.nupkg.sha512"
|
||||
},
|
||||
"System.Diagnostics.DiagnosticSource/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-tCQTzPsGZh/A9LhhA6zrqCRV4hOHsK90/G7q3Khxmn6tnB1PuNU0cRaKANP2AWcF9bn0zsuOoZOSrHuJk6oNBA==",
|
||||
"path": "system.diagnostics.diagnosticsource/5.0.0",
|
||||
"hashPath": "system.diagnostics.diagnosticsource.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==",
|
||||
"path": "system.runtime.compilerservices.unsafe/5.0.0",
|
||||
"hashPath": "system.runtime.compilerservices.unsafe.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Text.Encodings.Web/5.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-KmJ+CJXizDofbq6mpqDoRRLcxgOd2z9X3XoFNULSbvbqVRZkFX3istvr+MUjL6Zw1RT+RNdoI4GYidIINtgvqQ==",
|
||||
"path": "system.text.encodings.web/5.0.1",
|
||||
"hashPath": "system.text.encodings.web.5.0.1.nupkg.sha512"
|
||||
},
|
||||
"System.Text.Json/5.0.2": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-I47dVIGiV6SfAyppphxqupertT/5oZkYLDCX6vC3HpOI4ZLjyoKAreUoem2ie6G0RbRuFrlqz/PcTQjfb2DOfQ==",
|
||||
"path": "system.text.json/5.0.2",
|
||||
"hashPath": "system.text.json.5.0.2.nupkg.sha512"
|
||||
},
|
||||
"Xarial.XCad/0.7.4": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-HkTqmme828wJ/RDFnfieWZkvTdXFBdO2p6trMUiDa4P9P5C7gLfXslfG5q2CZ9d4vhSXjfweWSrp1ucSBqM6sg==",
|
||||
"path": "xarial.xcad/0.7.4",
|
||||
"hashPath": "xarial.xcad.0.7.4.nupkg.sha512"
|
||||
},
|
||||
"Xarial.XCad.SolidWorks/0.7.4": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-n2UP+Z/5Sxrt64taarHXqerp3sKYLv4f+CBmkxKAuFFX/8McxXiJIud0iRwfGeIEOxrd0iYlNQXxzy3JVJiMWQ==",
|
||||
"path": "xarial.xcad.solidworks/0.7.4",
|
||||
"hashPath": "xarial.xcad.solidworks.0.7.4.nupkg.sha512"
|
||||
},
|
||||
"Xarial.XCad.SolidWorks.Interops/0.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-ebiAAOHtYpZfjbO4PgdWcmv8+YtoPfAJwUJBeUM2SEBxO1+ru2dYI0XI2Fa1MpmAlsDRuBj6Z3LKtZMtff6NEQ==",
|
||||
"path": "xarial.xcad.solidworks.interops/0.3.0",
|
||||
"hashPath": "xarial.xcad.solidworks.interops.0.3.0.nupkg.sha512"
|
||||
},
|
||||
"Xarial.XCad.Toolkit/0.7.4": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-xJKIqEzdZKst+KmDZl1EvIsUebEEBa1yVmH2GpKHYQJkDhAakBfRQYO4/70/z3Qi/WmrNULq95F+lYc4mUoOTQ==",
|
||||
"path": "xarial.xcad.toolkit/0.7.4",
|
||||
"hashPath": "xarial.xcad.toolkit.0.7.4.nupkg.sha512"
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
packages/cad/sw/2020/bom.dll
Normal file
BIN
packages/cad/sw/2020/bom.dll
Normal file
Binary file not shown.
BIN
packages/cad/sw/2020/bom.exe
Normal file
BIN
packages/cad/sw/2020/bom.exe
Normal file
Binary file not shown.
8
packages/cad/sw/2020/bom.runtimeconfig.dev.json
Normal file
8
packages/cad/sw/2020/bom.runtimeconfig.dev.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"additionalProbingPaths": [
|
||||
"C:\\Users\\mc007\\.dotnet\\store\\|arch|\\|tfm|",
|
||||
"C:\\Users\\mc007\\.nuget\\packages"
|
||||
]
|
||||
}
|
||||
}
|
||||
9
packages/cad/sw/2020/bom.runtimeconfig.json
Normal file
9
packages/cad/sw/2020/bom.runtimeconfig.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "netcoreapp3.1",
|
||||
"framework": {
|
||||
"name": "Microsoft.WindowsDesktop.App",
|
||||
"version": "3.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
5
packages/cad/sw/2020/export.cmd
Normal file
5
packages/cad/sw/2020/export.cmd
Normal file
@ -0,0 +1,5 @@
|
||||
SET inputFilePath=%1
|
||||
SET outFilePath=%2
|
||||
SET view=%3
|
||||
|
||||
PowerShell -NoProfile -ExecutionPolicy Bypass -File "%~dp0export.ps1" %inputFilePath% %outFilePath% %view%
|
||||
108
packages/cad/sw/2020/export.cs
Normal file
108
packages/cad/sw/2020/export.cs
Normal file
@ -0,0 +1,108 @@
|
||||
using SolidWorks.Interop.sldworks;
|
||||
using System;
|
||||
|
||||
namespace CodeStack
|
||||
{
|
||||
public static class Exporter
|
||||
{
|
||||
#region Libraries
|
||||
|
||||
static Exporter()
|
||||
{
|
||||
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
|
||||
}
|
||||
|
||||
public static void LoadLibrary(params object[] libs)
|
||||
{
|
||||
foreach(string lib in libs)
|
||||
{
|
||||
Console.WriteLine(string.Format("Loading library: {0}", lib));
|
||||
System.Reflection.Assembly assm = System.Reflection.Assembly.LoadFrom(lib);
|
||||
Console.WriteLine(assm.GetName().ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private static System.Reflection.Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
|
||||
{
|
||||
foreach (System.Reflection.Assembly assm in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
if(assm.GetName().ToString() == args.Name)
|
||||
{
|
||||
return assm;
|
||||
}
|
||||
};
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public static void ExportFile(string filePath, string outFilePath, string view)
|
||||
{
|
||||
Console.WriteLine("Connecting to SOLIDWORKS...");
|
||||
|
||||
ISldWorks app = Activator.CreateInstance(Type.GetTypeFromProgID("SldWorks.Application")) as ISldWorks;
|
||||
|
||||
if (app != null)
|
||||
{
|
||||
Console.WriteLine(string.Format("Opening file '{0}'...", filePath));
|
||||
|
||||
IDocumentSpecification docSpec = app.GetOpenDocSpec(filePath) as IDocumentSpecification;
|
||||
docSpec.ReadOnly = true;
|
||||
docSpec.Silent = true;
|
||||
IModelDoc2 model = app.OpenDoc7(docSpec);
|
||||
model.ShowNamedView2(view,-1);
|
||||
model.ViewZoomtofit2();
|
||||
|
||||
int swViewDisplayHideAllTypes = 198;
|
||||
model.SetUserPreferenceToggle(swViewDisplayHideAllTypes, true);
|
||||
|
||||
// DrawingDoc swDraw = model as DrawingDoc;
|
||||
// View swView = swDraw.GetFirstView() as View;
|
||||
|
||||
// view.SetDisplayMode3(False, 4, false, false);
|
||||
|
||||
/*Member Description
|
||||
swDisplayModeDEFAULT 8
|
||||
swDisplayModeUNKNOWN -1
|
||||
swFACETED_HIDDEN 6
|
||||
swFACETED_HIDDEN_GREYED 5
|
||||
swFACETED_WIREFRAME 4
|
||||
swHIDDEN 2; Hidden Lines Removed (HLR)
|
||||
swHIDDEN_GREYED 1; Hidden Lines Visible (HLV)
|
||||
swSHADED 3
|
||||
swSHADED_EDGES 7
|
||||
swWIREFRAME 0
|
||||
*/
|
||||
|
||||
if (model != null)
|
||||
{
|
||||
const int swSaveAsCurrentVersion = 0;
|
||||
const int swSaveAsOptions_Silent = 1;
|
||||
int err = -1;
|
||||
int warn = -1;
|
||||
|
||||
Console.WriteLine(string.Format("Exporting file '{0}' to '{1}'...", filePath, outFilePath));
|
||||
|
||||
if (!model.Extension.SaveAs(outFilePath, swSaveAsCurrentVersion,
|
||||
swSaveAsOptions_Silent, null, ref err, ref warn))
|
||||
{
|
||||
Console.WriteLine(string.Format("Failed to export '{0}' to '{1}'. Error code: {2}", filePath, outFilePath, err));
|
||||
}
|
||||
|
||||
Console.WriteLine(string.Format("Closing file '{0}'...", filePath));
|
||||
|
||||
app.CloseDoc(model.GetTitle());
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(string.Format("Failed to open document: '{0}'. Error code: {1}",filePath, docSpec.Error));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Failed to connect to SOLIDWORKS instance");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user