cleanup
This commit is contained in:
parent
1c80f39936
commit
9223a53c7a
@ -1 +0,0 @@
|
||||
{}
|
||||
17
products/poly-mech/.gitattributes
vendored
17
products/poly-mech/.gitattributes
vendored
@ -1,17 +0,0 @@
|
||||
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||
*.igs filter=lfs diff=lfs merge=lfs -text
|
||||
*.iges filter=lfs diff=lfs merge=lfs -text
|
||||
*.step filter=lfs diff=lfs merge=lfs -text
|
||||
SLDASM filter=lfs diff=lfs merge=lfs -text
|
||||
STEP filter=lfs diff=lfs merge=lfs -text
|
||||
jpg filter=lfs diff=lfs merge=lfs -text
|
||||
*.SLDASM filter=lfs diff=lfs merge=lfs -text
|
||||
*.jpg filter=lfs diff=lfs merge=lfs -text
|
||||
*.png filter=lfs diff=lfs merge=lfs -text
|
||||
*.SLDPRT filter=lfs diff=lfs merge=lfs -text
|
||||
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||
*.mp4 filter=lfs diff=lfs merge=lfs -text
|
||||
*.x_t filter=lfs diff=lfs merge=lfs -text
|
||||
*.exe filter=lfs diff=lfs merge=lfs -text
|
||||
*.mkv filter=lfs diff=lfs merge=lfs -text
|
||||
*.ARW filter=lfs diff=lfs merge=lfs -text
|
||||
4
products/poly-mech/.gitignore
vendored
4
products/poly-mech/.gitignore
vendored
@ -1,4 +0,0 @@
|
||||
/node_modules
|
||||
/coverage
|
||||
*.log
|
||||
.DS_Store
|
||||
@ -1,39 +0,0 @@
|
||||
stages:
|
||||
- build
|
||||
|
||||
variables:
|
||||
HUGO_ENV: production
|
||||
HUGO_VERSION: "0.115.1"
|
||||
GO_VERSION: "1.20.5"
|
||||
NODE_VERSION: "18.16.1"
|
||||
|
||||
cache:
|
||||
paths:
|
||||
- node_modules/
|
||||
|
||||
default:
|
||||
image: node:${NODE_VERSION}
|
||||
before_script:
|
||||
- echo "USING NODE ${NODE_VERSION}"
|
||||
- apt-get update && apt-get install -y curl
|
||||
- curl -LO "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz"
|
||||
- tar -xvf hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz
|
||||
- mv hugo /usr/local/bin/
|
||||
- rm hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz
|
||||
- echo "HUGO ${HUGO_VERSION} INSTALLED"
|
||||
- curl -LO "https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz"
|
||||
- tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz
|
||||
- export PATH=$PATH:/usr/local/go/bin
|
||||
- rm go${GO_VERSION}.linux-amd64.tar.gz
|
||||
- echo "GO ${GO_VERSION} INSTALLED"
|
||||
- npm install
|
||||
|
||||
pages:
|
||||
stage: build
|
||||
script:
|
||||
- npm run project-setup
|
||||
- npm run build
|
||||
- echo "SITE BUILT SUCCESSFULLY! LIVE AT https://$GITLAB_USER_LOGIN.gitlab.io/$CI_PROJECT_NAME/"
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
@ -1,59 +0,0 @@
|
||||
{
|
||||
"maxerr": 50,
|
||||
"bitwise": true,
|
||||
"camelcase": false,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"forin": true,
|
||||
"freeze": true,
|
||||
"immed": true,
|
||||
"indent": 2,
|
||||
"latedef": true,
|
||||
"newcap": false,
|
||||
"noarg": true,
|
||||
"noempty": true,
|
||||
"nonbsp": true,
|
||||
"nonew": true,
|
||||
"plusplus": false,
|
||||
"undef": true,
|
||||
"unused": false,
|
||||
"strict": true,
|
||||
"maxparams": false,
|
||||
"maxdepth": 4,
|
||||
"maxstatements": false,
|
||||
"maxcomplexity": false,
|
||||
"maxlen": 400,
|
||||
"browser": true,
|
||||
"devel": true,
|
||||
"asi": false,
|
||||
"boss": false,
|
||||
"debug": false,
|
||||
"eqnull": false,
|
||||
"es3": false,
|
||||
"es5": false,
|
||||
"esversion": 12,
|
||||
"moz": false,
|
||||
"evil": true,
|
||||
"expr": true,
|
||||
"funcscope": false,
|
||||
"globalstrict": false,
|
||||
"iterator": false,
|
||||
"lastsemic": false,
|
||||
"laxbreak": false,
|
||||
"laxcomma": false,
|
||||
"loopfunc": true,
|
||||
"multistr": true,
|
||||
"noyield": false,
|
||||
"notypeof": false,
|
||||
"proto": false,
|
||||
"scripturl": false,
|
||||
"shadow": false,
|
||||
"sub": false,
|
||||
"supernew": false,
|
||||
"validthis": false,
|
||||
"globals": {
|
||||
"jQuery": false,
|
||||
"google": false,
|
||||
"$": false
|
||||
}
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
./docs
|
||||
./scripts
|
||||
./tests
|
||||
./incoming
|
||||
@ -1,20 +0,0 @@
|
||||
{
|
||||
"debug": true,
|
||||
"matching": [
|
||||
"*.json",
|
||||
"*.md",
|
||||
"*.yaml",
|
||||
"*.csv",
|
||||
"*.xls",
|
||||
"*.xlsx",
|
||||
"*.ods",
|
||||
"*.osrl",
|
||||
"*.txt",
|
||||
"media/gallery/**",
|
||||
"resources/**",
|
||||
"drawings/**",
|
||||
"firmware/**",
|
||||
"howto/**",
|
||||
"renderings/**"
|
||||
]
|
||||
}
|
||||
@ -1,66 +0,0 @@
|
||||
{
|
||||
"includes": [
|
||||
"${root}/osr",
|
||||
"${root}/osr/library",
|
||||
"${root}/osr/widgets",
|
||||
"${root}/osr/commons",
|
||||
"${cwd}/osr",
|
||||
"${cwd}/osr/library",
|
||||
"${cwd}/osr/widgets",
|
||||
"${cwd}/osr/commons",
|
||||
"${cwd}/src/data",
|
||||
"${cwd}/src/data-en",
|
||||
"${cwd}/src/data-es",
|
||||
"${cwd}/src/data-fr"
|
||||
],
|
||||
"variables": {
|
||||
"PRODUCT_ROOT": "${root}/${product}/",
|
||||
"_abs_url": "https://plastic-hub.com",
|
||||
"abs_url": "https://plastic-hub.com/",
|
||||
"CACHE": "${root}/cache/",
|
||||
"CACHE_URL": "${abs_url}/cache/",
|
||||
"GIT_REPO": "https://git.osr-plastic.org/osr-plastic/osr-machines",
|
||||
"OSR_MACHINES_ASSETS_URL":"https://assets.osr-plastic.org/machines/",
|
||||
"PRODUCTS_ASSETS_URL":"https://assets.osr-plastic.org/machines/${product}",
|
||||
"OSR_FILES_WEB":"https://files.osr-plastic.org/files/osr-machines",
|
||||
"PRODUCTS_FILES_URL":"${OSR_FILES_WEB}/${product_rel}",
|
||||
"DISCORD":"https://discord.gg/s8K7yKwBRc"
|
||||
},
|
||||
"env": {
|
||||
"library": {
|
||||
"includes": [
|
||||
"${PRODUCT_ROOT}/templates/shared/",
|
||||
"${root}/osr",
|
||||
"${root}/osr/widgets",
|
||||
"${root}/osr/commons"
|
||||
],
|
||||
"variables": {
|
||||
"abs_url": "http://localhost:8008/"
|
||||
}
|
||||
},
|
||||
"library-release": {
|
||||
"includes": [
|
||||
"${PRODUCT_ROOT}/templates/shared/",
|
||||
"${root}/osr",
|
||||
"${root}/osr/widgets",
|
||||
"${PRODUCT_ROOT}"
|
||||
],
|
||||
"variables": {
|
||||
"abs_url": "https://osr-plastic.org"
|
||||
}
|
||||
},
|
||||
"hugo-release": {
|
||||
"includes": [
|
||||
"${PRODUCT_ROOT}/templates/bazar",
|
||||
"${PRODUCT_ROOT}/templates/shared/",
|
||||
"${root}/osr",
|
||||
"${root}/osr/widgets",
|
||||
"${PRODUCT_ROOT}"
|
||||
],
|
||||
"variables": {
|
||||
"abs_url": "https://plastic-hub.com/",
|
||||
"OSR_MACHINES_ASSETS_URL": "https://assets.osr-plastic.org/machines/"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
132
products/poly-mech/.vscode/launch.json
vendored
132
products/poly-mech/.vscode/launch.json
vendored
@ -1,132 +0,0 @@
|
||||
{
|
||||
// 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": "Grunt - compile:content-en",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${env:APPDATA}\\npm\\node_modules\\grunt\\bin\\grunt",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"args": [
|
||||
"compile:content-en",
|
||||
"--verbose=false",
|
||||
"--cache=false",
|
||||
"--logLevel=trace",
|
||||
"--stack"
|
||||
] ,
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Grunt - Help",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${env:APPDATA}\\npm\\node_modules\\grunt\\bin\\grunt",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"args": [
|
||||
"--help",
|
||||
"--verbose=false",
|
||||
"--cache=true",
|
||||
"--logLevel=info",
|
||||
"--stack"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Grunt - Compile Products: Katbot : DE",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${env:APPDATA}\\npm\\node_modules\\grunt\\bin\\grunt",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"args": [
|
||||
"content-de-katbot-pro-mega-beta",
|
||||
"--verbose=false",
|
||||
"--logLevel=debug",
|
||||
"--stack"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Grunt - Compile Products : Product - EN",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${env:APPDATA}\\npm\\node_modules\\grunt\\bin\\grunt",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"args": [
|
||||
"compile:content-en-lydia-v4.5",
|
||||
"--content-de-katbot-pro-mega-beta",
|
||||
"--convertProductMedia=true",
|
||||
"--verbose=false",
|
||||
"--logLevel=debug",
|
||||
"--stack"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Grunt - Performance Profile",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${env:APPDATA}\\npm\\node_modules\\grunt\\bin\\grunt",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"args": [
|
||||
"--help",
|
||||
"--verbose=false",
|
||||
"--debug=true"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -1,199 +0,0 @@
|
||||
CERN Open Hardware Licence Version 2 - Permissive
|
||||
|
||||
|
||||
Preamble
|
||||
|
||||
CERN has developed this licence to promote collaboration among
|
||||
hardware designers and to provide a legal tool which supports the
|
||||
freedom to use, study, modify, share and distribute hardware designs
|
||||
and products based on those designs. Version 2 of the CERN Open
|
||||
Hardware Licence comes in three variants: this licence, CERN-OHL-P
|
||||
(permissive); and two reciprocal licences: CERN-OHL-W (weakly
|
||||
reciprocal) and CERN-OHL-S (strongly reciprocal).
|
||||
|
||||
The CERN-OHL-P is copyright CERN 2020. Anyone is welcome to use it, in
|
||||
unmodified form only.
|
||||
|
||||
Use of this Licence does not imply any endorsement by CERN of any
|
||||
Licensor or their designs nor does it imply any involvement by CERN in
|
||||
their development.
|
||||
|
||||
|
||||
1 Definitions
|
||||
|
||||
1.1 'Licence' means this CERN-OHL-P.
|
||||
|
||||
1.2 'Source' means information such as design materials or digital
|
||||
code which can be applied to Make or test a Product or to
|
||||
prepare a Product for use, Conveyance or sale, regardless of its
|
||||
medium or how it is expressed. It may include Notices.
|
||||
|
||||
1.3 'Covered Source' means Source that is explicitly made available
|
||||
under this Licence.
|
||||
|
||||
1.4 'Product' means any device, component, work or physical object,
|
||||
whether in finished or intermediate form, arising from the use,
|
||||
application or processing of Covered Source.
|
||||
|
||||
1.5 'Make' means to create or configure something, whether by
|
||||
manufacture, assembly, compiling, loading or applying Covered
|
||||
Source or another Product or otherwise.
|
||||
|
||||
1.6 'Notice' means copyright, acknowledgement and trademark notices,
|
||||
references to the location of any Notices, modification notices
|
||||
(subsection 3.3(b)) and all notices that refer to this Licence
|
||||
and to the disclaimer of warranties that are included in the
|
||||
Covered Source.
|
||||
|
||||
1.7 'Licensee' or 'You' means any person exercising rights under
|
||||
this Licence.
|
||||
|
||||
1.8 'Licensor' means a person who creates Source or modifies Covered
|
||||
Source and subsequently Conveys the resulting Covered Source
|
||||
under the terms and conditions of this Licence. A person may be
|
||||
a Licensee and a Licensor at the same time.
|
||||
|
||||
1.9 'Convey' means to communicate to the public or distribute.
|
||||
|
||||
|
||||
2 Applicability
|
||||
|
||||
2.1 This Licence governs the use, copying, modification, Conveying
|
||||
of Covered Source and Products, and the Making of Products. By
|
||||
exercising any right granted under this Licence, You irrevocably
|
||||
accept these terms and conditions.
|
||||
|
||||
2.2 This Licence is granted by the Licensor directly to You, and
|
||||
shall apply worldwide and without limitation in time.
|
||||
|
||||
2.3 You shall not attempt to restrict by contract or otherwise the
|
||||
rights granted under this Licence to other Licensees.
|
||||
|
||||
2.4 This Licence is not intended to restrict fair use, fair dealing,
|
||||
or any other similar right.
|
||||
|
||||
|
||||
3 Copying, Modifying and Conveying Covered Source
|
||||
|
||||
3.1 You may copy and Convey verbatim copies of Covered Source, in
|
||||
any medium, provided You retain all Notices.
|
||||
|
||||
3.2 You may modify Covered Source, other than Notices.
|
||||
|
||||
You may only delete Notices if they are no longer applicable to
|
||||
the corresponding Covered Source as modified by You and You may
|
||||
add additional Notices applicable to Your modifications.
|
||||
|
||||
3.3 You may Convey modified Covered Source (with the effect that You
|
||||
shall also become a Licensor) provided that You:
|
||||
|
||||
a) retain Notices as required in subsection 3.2; and
|
||||
|
||||
b) add a Notice to the modified Covered Source stating that You
|
||||
have modified it, with the date and brief description of how
|
||||
You have modified it.
|
||||
|
||||
3.4 You may Convey Covered Source or modified Covered Source under
|
||||
licence terms which differ from the terms of this Licence
|
||||
provided that:
|
||||
|
||||
a) You comply at all times with subsection 3.3; and
|
||||
|
||||
b) You provide a copy of this Licence to anyone to whom You
|
||||
Convey Covered Source or modified Covered Source.
|
||||
|
||||
|
||||
4 Making and Conveying Products
|
||||
|
||||
You may Make Products, and/or Convey them, provided that You ensure
|
||||
that the recipient of the Product has access to any Notices applicable
|
||||
to the Product.
|
||||
|
||||
|
||||
5 DISCLAIMER AND LIABILITY
|
||||
|
||||
5.1 DISCLAIMER OF WARRANTY -- The Covered Source and any Products
|
||||
are provided 'as is' and any express or implied warranties,
|
||||
including, but not limited to, implied warranties of
|
||||
merchantability, of satisfactory quality, non-infringement of
|
||||
third party rights, and fitness for a particular purpose or use
|
||||
are disclaimed in respect of any Source or Product to the
|
||||
maximum extent permitted by law. The Licensor makes no
|
||||
representation that any Source or Product does not or will not
|
||||
infringe any patent, copyright, trade secret or other
|
||||
proprietary right. The entire risk as to the use, quality, and
|
||||
performance of any Source or Product shall be with You and not
|
||||
the Licensor. This disclaimer of warranty is an essential part
|
||||
of this Licence and a condition for the grant of any rights
|
||||
granted under this Licence.
|
||||
|
||||
5.2 EXCLUSION AND LIMITATION OF LIABILITY -- The Licensor shall, to
|
||||
the maximum extent permitted by law, have no liability for
|
||||
direct, indirect, special, incidental, consequential, exemplary,
|
||||
punitive or other damages of any character including, without
|
||||
limitation, procurement of substitute goods or services, loss of
|
||||
use, data or profits, or business interruption, however caused
|
||||
and on any theory of contract, warranty, tort (including
|
||||
negligence), product liability or otherwise, arising in any way
|
||||
in relation to the Covered Source, modified Covered Source
|
||||
and/or the Making or Conveyance of a Product, even if advised of
|
||||
the possibility of such damages, and You shall hold the
|
||||
Licensor(s) free and harmless from any liability, costs,
|
||||
damages, fees and expenses, including claims by third parties,
|
||||
in relation to such use.
|
||||
|
||||
|
||||
6 Patents
|
||||
|
||||
6.1 Subject to the terms and conditions of this Licence, each
|
||||
Licensor hereby grants to You a perpetual, worldwide,
|
||||
non-exclusive, no-charge, royalty-free, irrevocable (except as
|
||||
stated in this section 6, or where terminated by the Licensor
|
||||
for cause) patent license to Make, have Made, use, offer to
|
||||
sell, sell, import, and otherwise transfer the Covered Source
|
||||
and Products, where such licence applies only to those patent
|
||||
claims licensable by such Licensor that are necessarily
|
||||
infringed by exercising rights under the Covered Source as
|
||||
Conveyed by that Licensor.
|
||||
|
||||
6.2 If You institute patent litigation against any entity (including
|
||||
a cross-claim or counterclaim in a lawsuit) alleging that the
|
||||
Covered Source or a Product constitutes direct or contributory
|
||||
patent infringement, or You seek any declaration that a patent
|
||||
licensed to You under this Licence is invalid or unenforceable
|
||||
then any rights granted to You under this Licence shall
|
||||
terminate as of the date such process is initiated.
|
||||
|
||||
|
||||
7 General
|
||||
|
||||
7.1 If any provisions of this Licence are or subsequently become
|
||||
invalid or unenforceable for any reason, the remaining
|
||||
provisions shall remain effective.
|
||||
|
||||
7.2 You shall not use any of the name (including acronyms and
|
||||
abbreviations), image, or logo by which the Licensor or CERN is
|
||||
known, except where needed to comply with section 3, or where
|
||||
the use is otherwise allowed by law. Any such permitted use
|
||||
shall be factual and shall not be made so as to suggest any kind
|
||||
of endorsement or implication of involvement by the Licensor or
|
||||
its personnel.
|
||||
|
||||
7.3 CERN may publish updated versions and variants of this Licence
|
||||
which it considers to be in the spirit of this version, but may
|
||||
differ in detail to address new problems or concerns. New
|
||||
versions will be published with a unique version number and a
|
||||
variant identifier specifying the variant. If the Licensor has
|
||||
specified that a given variant applies to the Covered Source
|
||||
without specifying a version, You may treat that Covered Source
|
||||
as being released under any version of the CERN-OHL with that
|
||||
variant. If no variant is specified, the Covered Source shall be
|
||||
treated as being released under CERN-OHL-S. The Licensor may
|
||||
also specify that the Covered Source is subject to a specific
|
||||
version of the CERN-OHL or any later version in which case You
|
||||
may apply this or any later version of CERN-OHL with the same
|
||||
variant identifier published by CERN.
|
||||
|
||||
7.4 This Licence shall not be enforceable except by a Licensor
|
||||
acting as such, and third party beneficiary rights are
|
||||
specifically excluded.
|
||||
@ -1,102 +0,0 @@
|
||||
## Components
|
||||
|
||||
- [ ] joints
|
||||
- [ ] stationary
|
||||
- [ ] compats
|
||||
- [ ] fasteners
|
||||
- [ ] base
|
||||
- [ ] axial
|
||||
- [ ] linear
|
||||
- [ ] glide
|
||||
|
||||
## Moulds
|
||||
|
||||
- [ ] beam
|
||||
- [ ] quad
|
||||
- [ ] continous
|
||||
- [ ] inserts
|
||||
|
||||
## Research
|
||||
|
||||
- [ ] Spacing
|
||||
- [ ] Language
|
||||
- [ ] [Structural formula](https://en.wikipedia.org/wiki/Structural_formula) (2D)
|
||||
- [ ] [Fischer Projection](https://en.wikipedia.org/wiki/Fischer_projection)
|
||||
- [ ] [Skeletal formula](https://en.wikipedia.org/wiki/Skeletal_formula) (3D)
|
||||
- [ ] Simplified Representation | Nodes and Connectors | Angles and Bonds | Types of Joints | Planar vs. Spatial Diagrams
|
||||
- [ ] ``` □───○ (1,1) (4,5) ``` (sphere->shaft->box)
|
||||
- [ ] https://en.wikipedia.org/wiki/ACD/ChemSketch
|
||||
- [ ] [BPML](https://en.wikipedia.org/wiki/Business_Process_Modeling_Language)
|
||||
- [ ] [BPMN - Editor Web](https://bpmn.io/)
|
||||
|
||||
## Coding
|
||||
|
||||
- [x] SCAD alternative : https://implicitcad.org/editor (f** Haskell) | Generative Modeling Language (GML) is dead
|
||||
- [ ] Formats : SVG
|
||||
|
||||
## Model
|
||||
|
||||
- [ ] Primitives
|
||||
- [ ] Patterns (lang/format agnostic)
|
||||
|
||||
## Units
|
||||
|
||||
- [ ] imperial
|
||||
|
||||
## Fasteners
|
||||
|
||||
### Structures
|
||||
|
||||
- [Aluminium Tubings](./resources/framework/al-tubings.md)
|
||||
- [Bamboo](./resources/framework/bamboo.md)
|
||||
|
||||
## Motion
|
||||
|
||||
- [SBR / SBUU](./resources/motion/sbr/readme.md)
|
||||
- [Bearings]
|
||||
|
||||
## Connectivity
|
||||
|
||||
- [Hoses]
|
||||
|
||||
## Materials & Tests
|
||||
|
||||
- [HDPE](./resources/material/hdpe/)
|
||||
|
||||
## Projects / Applications
|
||||
|
||||
- [ ] Cart
|
||||
- [ ] suspension
|
||||
- [ ] adjustable shelfs
|
||||
- [ ] stands
|
||||
- [ ] [AV gear](./resources/products/av/readme.md)
|
||||
|
||||
## Production
|
||||
|
||||
## CAM
|
||||
|
||||
## Resources
|
||||
|
||||
### Bearings
|
||||
|
||||
- https://www.123rodamiento.es/rodamiento-cojinete/transmision-lineal/rodamiento-linear/lbbr25-skf
|
||||
|
||||
### Funding
|
||||
|
||||
- [Crowdfunding](./resources/funding/readme.md)
|
||||
|
||||
### Related Projects
|
||||
|
||||
- [Gridbeams](./resources/projects/gridbeams.md)
|
||||
|
||||
## OSR - Tooling Todos
|
||||
|
||||
### Generative CAD
|
||||
|
||||
- [ ] OSR-AI (gpt4-o) -> OpenSCAD -> FreeCAD (FreeCADCmd - STEP) -> Solidworks (FeatureWorks) -> OSR
|
||||
- [ ] GrabCAD / PartTrace
|
||||
- [ ] www.rapiddirect.com
|
||||
|
||||
### OSR-CAD
|
||||
|
||||
- [ ] SW->Composer->SVG->Draw.io symbol/library
|
||||
12
products/poly-mech/cad/.gitattributes
vendored
12
products/poly-mech/cad/.gitattributes
vendored
@ -1,12 +0,0 @@
|
||||
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||
*.igs filter=lfs diff=lfs merge=lfs -text
|
||||
*.iges filter=lfs diff=lfs merge=lfs -text
|
||||
*.step filter=lfs diff=lfs merge=lfs -text
|
||||
SLDASM filter=lfs diff=lfs merge=lfs -text
|
||||
STEP filter=lfs diff=lfs merge=lfs -text
|
||||
jpg filter=lfs diff=lfs merge=lfs -text
|
||||
*.SLDASM filter=lfs diff=lfs merge=lfs -text
|
||||
*.jpg filter=lfs diff=lfs merge=lfs -text
|
||||
*.png filter=lfs diff=lfs merge=lfs -text
|
||||
*.SLDPRT filter=lfs diff=lfs merge=lfs -text
|
||||
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||
@ -1,45 +0,0 @@
|
||||
{
|
||||
"includes": [
|
||||
"${PRODUCT_ROOT}",
|
||||
"${PRODUCT_ROOT}/templates/library/",
|
||||
"${PRODUCT_ROOT}/templates/shared/",
|
||||
"${root}/osr",
|
||||
"${root}/osr/library",
|
||||
"${root}/osr/widgets",
|
||||
"${root}/_includes",
|
||||
"${root}/templates/site/"
|
||||
],
|
||||
"variables": {
|
||||
"PRODUCT_ROOT": "${root}/${product}/",
|
||||
"_abs_url": "https://plastic-hub.com",
|
||||
"abs_url": "https://plastic-hub.com/",
|
||||
"CACHE": "${root}/cache/",
|
||||
"CACHE_URL": "${abs_url}/cache/",
|
||||
"MAGENTO_URL": "https://shop.plastic-hub.com"
|
||||
},
|
||||
"env": {
|
||||
"library": {
|
||||
"includes": [
|
||||
"${PRODUCT_ROOT}/templates/shared/",
|
||||
"${root}/osr",
|
||||
"${root}/osr/widgets",
|
||||
"${PRODUCT_ROOT}"
|
||||
],
|
||||
"variables": {
|
||||
"abs_url": "http://localhost:8008/",
|
||||
"MAGENTO_URL": "https://shop.plastic-hub.com"
|
||||
}
|
||||
},
|
||||
"library-release": {
|
||||
"includes": [
|
||||
"${PRODUCT_ROOT}/templates/shared/",
|
||||
"${root}/osr",
|
||||
"${root}/osr/widgets",
|
||||
"${PRODUCT_ROOT}"
|
||||
],
|
||||
"variables": {
|
||||
"abs_url": "https://osr-plastic.org"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
products/poly-mech/cad/bins/media/DSC03635.JPG
(Stored with Git LFS)
BIN
products/poly-mech/cad/bins/media/DSC03635.JPG
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/chairs/pm-50/Main-5050.jpg
(Stored with Git LFS)
BIN
products/poly-mech/cad/chairs/pm-50/Main-5050.jpg
(Stored with Git LFS)
Binary file not shown.
@ -1,8 +0,0 @@
|
||||
[
|
||||
{
|
||||
"File Path": "C:\\Users\\zx\\Desktop\\osr\\products\\products\\products\\poly-mech\\cad\\chairs\\pm-50\\Main-5050.SLDASM"
|
||||
},
|
||||
{
|
||||
"File Path": "C:\\Users\\zx\\Desktop\\osr\\products\\products\\products\\poly-mech\\cad\\chairs\\pm-50\\Legs-50-50.SLDASM"
|
||||
}
|
||||
]
|
||||
BIN
products/poly-mech/cad/chairs/pm-50/Main-5050.step
(Stored with Git LFS)
BIN
products/poly-mech/cad/chairs/pm-50/Main-5050.step
(Stored with Git LFS)
Binary file not shown.
@ -1,97 +0,0 @@
|
||||
# **Analysis of Standard Gas Lift Suppliers for Office Chairs in Spain and Europe**
|
||||
|
||||
## **1\. Executive Summary**
|
||||
|
||||
This report identifies key suppliers of standard gas lifts for office chairs located in Spain and across Europe. The analysis reveals a varied market with options ranging from direct manufacturers and specialized retailers to general e-commerce platforms. Prices for standard gas lifts vary depending on the supplier, features, and intended use, with some suppliers focusing on specific chair models while others offer more universal solutions. Key Spanish suppliers identified include STUA Design Shop, primarily a furniture manufacturer that also offers replacement gas lifts for its own chairs, and Ubuy, an online marketplace providing access to a broader range of brands like Artilife. Across Europe, prominent suppliers include Stabilus, a German manufacturer specializing in ergonomic motion control technology for office furniture, Techly, an Italian-based supplier offering affordable standard gas lifts, The Chair Clinic Ltd from the UK, providing a comprehensive range of replacement gas lifts with certifications, Proroll, a German manufacturer emphasizing comfort and durability with customizable options, and Leikurvo and Mastery Mart, both offering widely compatible gas lifts through major e-commerce platforms. The diverse nature of these suppliers suggests a well-established market for office chair components within Europe, offering numerous choices for both localized and broader sourcing 1.
|
||||
|
||||
## **2\. Spanish Suppliers of Standard Gas Lifts**
|
||||
|
||||
### **2.1. STUA Design Shop**
|
||||
|
||||
STUA Design Shop, a family business rooted in Astigarraga, near San Sebastian, Spain, is known for its high-quality furniture and meticulous attention to detail 1. While primarily a furniture manufacturer, STUA also provides spare parts, including gas lift cylinders specifically designed for their "Gas Chair" model 1. These replacement gas lifts are available in white, priced at €65, black, priced at $95, and chrome, also priced at €65 1. STUA emphasizes the durability of its furniture, crafted with European raw materials, and backs this with a five-year guarantee on its designs 1. For customers within continental Europe, STUA offers a flat rate shipping fee of €30, and delivery typically takes around two weeks 1. STUA has received the National Design Award, further highlighting its commitment to quality and design 1. The availability of these specific replacement parts directly from the manufacturer ensures optimal compatibility for owners of STUA's "Gas Chair." However, the specialized nature of these gas lifts might limit their applicability to other office chair brands or models 1. The pricing of STUA's gas lifts, at €65 and $95, appears to be at the higher end compared to some other suppliers. This could be attributed to the premium quality of materials used, the five-year guarantee offered, and the reputation of STUA as a design-focused manufacturer, positioning them as a premium option for their specific clientele 1.
|
||||
|
||||
### **2.2. Ubuy (Reseller)**
|
||||
|
||||
Ubuy, an online marketplace, lists the "Artilife Office Chair Gas Lift Cylinder Direct Replacement" as available for delivery within Spain 5. This product is priced at €48, and the listing indicates a minimum delivery time of 10 days 5. It is important to note that Ubuy acts as a platform for various sellers, and in this case, Artilife is the manufacturer of the gas lift cylinder 5. The Artilife gas lift is described as a heavy-duty pneumatic cylinder suitable for office chairs with pneumatic lift systems, constructed from durable 45\# steel material with safety and explosion protection features 5. It offers an adjustable range of 5 inches and is designed for easy installation and replacement 5. The product has received positive customer feedback, with a 4.6-star rating, suggesting a level of satisfaction among users 5. Ubuy's role as a reseller provides access to a wider variety of gas lift options, including the Artilife brand, potentially offering a more budget-friendly alternative compared to purchasing directly from some manufacturers 5. However, as a marketplace, delivery times might be longer as Ubuy relies on third-party logistics for fulfillment 5. The availability of this product on Ubuy's Spanish platform signifies an existing demand within Spain for replacement gas lifts, and Ubuy is addressing this need by offering products from international brands like Artilife 5.
|
||||
|
||||
## **3\. European Suppliers of Standard Gas Lifts (Excluding Spain)**
|
||||
|
||||
### **3.1. Stabilus (Germany)**
|
||||
|
||||
Stabilus, a German company, is a prominent manufacturer of motion control technology, including a wide range of gas springs specifically designed for office furniture 2. The company emphasizes ergonomic solutions, with its gas springs facilitating adjustments for seat height, backrest, and seat angle in office chairs 2. Stabilus primarily operates as a business-to-business (B2B) supplier, collaborating closely with office furniture manufacturers to develop and supply customized gas spring columns tailored to specific applications 2. Their product offerings include columns with integrated depth suspension, comfortable deflection, telescoping outer tubes, and multi-function capabilities 2. Stabilus has established itself as a pioneer in the development of gas springs for ergonomic seating in the swivel chair industry, consistently refining its products to meet the evolving needs of the market 2. While Stabilus is a key European manufacturer, its primary focus on B2B partnerships and customized solutions might make it less accessible for individual consumers or businesses seeking standard, off-the-shelf replacement gas lifts 2. However, their strong emphasis on ergonomics and customization indicates their significant role in the high-quality office chair market, with their components likely contributing to the functionality and comfort of numerous European-made office chairs 2.
|
||||
|
||||
### **3.2. Techly (Italy \- inferred)**
|
||||
|
||||
Techly, inferred to be based in Italy, offers a black adjustable gas lift for office chairs at a competitive price of €14.40, including VAT 8. The product page provides detailed specifications, including an adjustable length ranging from 28 to 39 cm, a cylinder diameter of 40 mm at the bottom and 50 mm at the top, and a piston diameter of 28 mm 8. Techly also lists specific office chair models with which this gas lift is compatible, providing a helpful reference for potential buyers 8. A supplier code (307483) is also provided for easy identification 8. This offering from Techly presents an affordable and readily available option for a standard replacement gas lift, particularly appealing to users who are aware of the required specifications or own one of the listed compatible chair models 8. The low price point makes it an attractive choice for budget-conscious buyers seeking a direct replacement part 8. Customer reviews for this product are available on the website, with some written in Italian, suggesting a strong presence in the Italian market 8. However, the website is presented in English, indicating an intention to serve a broader European customer base 8.
|
||||
|
||||
### **3.3. The Chair Clinic Ltd (UK)**
|
||||
|
||||
The Chair Clinic Ltd, based in the UK, specializes in providing a wide array of office chair components, including a comprehensive selection of replacement gas lifts 3. They offer various classes and lengths of gas lifts to suit different needs and chair types 3. The prices for their standard gas lifts range from £31.80 to £49.80, inclusive of VAT 3. The Chair Clinic also provides essential tools for gas lift removal and replacement, such as a gas lift removal tool and a gas lift saver tool, both priced at £24.00 (including VAT), and a gas lift bearing repair kit for £18.00 (including VAT) 3. Notably, all gas lifts supplied by The Chair Clinic are certified to BIFMA, SATRA & BS standards, ensuring a high level of quality and safety 3. This extensive selection, coupled with quality certifications, makes The Chair Clinic a reliable source for various gas lift requirements 3. However, given their location in the UK, potential buyers in Spain and other EU countries should factor in potential shipping costs and delivery times that might apply following Brexit 3.
|
||||
|
||||
### **3.4. Proroll (Germany)**
|
||||
|
||||
Proroll, a German manufacturer, specializes in gas springs for office chairs, emphasizing comfort and long-lasting durability 9. The company has redeveloped its gas springs with the X-Line series, which features spring-locked mechanisms designed for stepless height adjustment in various types of office seating, including swivel chairs, work chairs, armchairs, and stools 9. Proroll offers gas springs in various lengths, which are typically available from stock, with standard finishes including black powder-coated and chrome-plated. Other colors can also be provided upon request 9. All gas spring columns from Proroll are certified to EN Standard Class 4, indicating a high level of quality 9. Proroll offers both rotatable and twist-proof versions of its gas springs, with over 30 different chair column variations available 9. As a direct manufacturer, Proroll is likely to offer competitive pricing, especially for bulk orders, and the potential for customized solutions to meet specific requirements, making them a valuable partner for businesses or larger procurement needs 9. Their strong focus on quality, as evidenced by the Class 4 certification, suggests they cater to a market that prioritizes durability and specific performance characteristics 9. Contact information is readily available on their website for inquiries 9.
|
||||
|
||||
### **3.5. Leikurvo (via Amazon.de)**
|
||||
|
||||
Leikurvo offers gas lifts for office chairs through the Amazon.de platform 4. These gas lifts feature an adjustable total length ranging from 270 mm to 390 mm, making them suitable for a variety of standard-sized office chairs, desk chairs, and gaming chairs 4. The product description highlights quiet 360-degree rotation and a dampening feature (except at minimum height) designed to protect the spine from impact when sitting 4. Installation is described as easy, requiring no tools for replacement, which can typically be completed within five minutes 4. Leikurvo emphasizes the wide compatibility of its gas lifts with most standard office chairs, although users are advised to check the dimensions before purchasing 4. The gas lifts have undergone SGS testing, ensuring reliable quality and safety 4. Selling through Amazon.de provides a convenient and accessible option for many European customers, often with efficient shipping options 4. The claim of broad compatibility suggests that this product is intended as a general-purpose replacement, potentially suitable for users who may not know the precise specifications of their existing gas lift 4.
|
||||
|
||||
### **3.6. Mastery Mart (via Amazon.co.uk)**
|
||||
|
||||
Mastery Mart offers heavy-duty gas lift cylinders for office chairs through Amazon.co.uk 11. These gas lifts are available in various stroke lengths, including 4 inches, 5.5 inches, and 8 inches, catering to different height adjustment needs 11. They are certified to the highest safety Class 4 standard (SGS/BIFMA/TÜV), are explosion-proof, and have a maximum weight capacity of 1000 lbs (454 kg), making them suitable for more robust office chairs 11. Mastery Mart explicitly states that their pneumatic piston cylinders are designed to fit almost every office chair on the market, with the notable exception of IKEA chairs 11. The product page provides detailed measurements of the cylinder to help customers determine compatibility 11. The availability of a heavy-duty option with high safety certifications makes Mastery Mart a strong contender for users requiring a durable and reliable replacement gas lift, particularly for larger or more frequently used office chairs 11. However, similar to other UK-based suppliers, potential buyers in Spain and other EU countries should be mindful of potential shipping costs and delivery times associated with international orders following Brexit 11.
|
||||
|
||||
## **4\. Comparative Table of Standard Gas Lifts**
|
||||
|
||||
The following table summarizes key information for some of the identified standard gas lift suppliers:
|
||||
|
||||
| Supplier | Location | Product Description | Price (approx.) | Shipping to Spain/Europe | Key Features | Link |
|
||||
| :---- | :---- | :---- | :---- | :---- | :---- | :---- |
|
||||
| STUA Design Shop | Spain | GAS CHAIR Gas lift cylinder (White, Black, Chrome) | €65 / $95 | €30 flat rate within continental EU | Specifically for STUA "Gas Chair", 5-year guarantee | [https://stua.com/shop/product/gas-chair-gas-lift-cylinder-white/](https://stua.com/shop/product/gas-chair-gas-lift-cylinder-white/), [https://stua.store/product/gas-chair-gas-lift-cylinder/](https://stua.store/product/gas-chair-gas-lift-cylinder/), [https://stua.com/shop/product/gas-chair-gas-lift-cylinder-chrome/](https://stua.com/shop/product/gas-chair-gas-lift-cylinder-chrome/) |
|
||||
| Ubuy (Artilife) | Spain (Reseller) | Artilife Office Chair Gas Lift Cylinder | €48 | Varies by location | Heavy-duty, pneumatic, universal fit | (https://www.ubuy.com.es/en/product/1PY98SII-artilife-office-chair-gas-lift-cylinder-replacement-heavy-duty-hydraulic-pneumatic-shock-piston-univ) |
|
||||
| Techly | Italy (inferred) | Gas Lift for Office Chair Adjustable Height Black | €14.40 (incl. VAT) | Varies by location | Adjustable length, compatible with specific models | [https://www.techly.com/gas-lift-for-office-chair-adjustable-height-black.html](https://www.techly.com/gas-lift-for-office-chair-adjustable-height-black.html) |
|
||||
| The Chair Clinic Ltd | UK | Range of Replacement Office Chair Gas Lifts | £31.80 \- £49.80 (incl. VAT) | Varies by location | Wide range, BIFMA, SATRA & BS certified, tools available | [https://www.chairclinic.co.uk/office-chair-gas-lifts/](https://www.chairclinic.co.uk/office-chair-gas-lifts/) |
|
||||
| Proroll | Germany | Gas springs for swivel chairs | Price upon inquiry | Varies by location | Customizable, EN Standard Class 4 certified, various finishes | [https://proroll.de/en/gas-spring-dampers/](https://proroll.de/en/gas-spring-dampers/) |
|
||||
| Leikurvo (via Amazon.de) | \- | Gas Lift for Office Chair, Adjustable Length | Price varies on Amazon.de | Varies by location | Universal fit, easy installation, SGS tested | ([https://www.amazon.de/-/en/Leikurvo-Office-Chair-Total-Length/dp/B0CW5KFZ63](https://www.amazon.de/-/en/Leikurvo-Office-Chair-Total-Length/dp/B0CW5KFZ63)) |
|
||||
| Mastery Mart (via Amazon.co.uk) | \- | Heavy Duty Gas Lift Cylinder | Price varies on Amazon.co.uk | Varies by location | Heavy-duty (1000 lbs), Class 4 certified, universal fit (except IKEA) | ([https://www.amazon.co.uk/Mastery-Mart-Universal-Replacement-Pneumatic/dp/B0859WG3X8](https://www.amazon.co.uk/Mastery-Mart-Universal-Replacement-Pneumatic/dp/B0859WG3X8)) |
|
||||
|
||||
## **5\. Key Considerations for Procurement**
|
||||
|
||||
When sourcing a standard gas lift for an office chair, several factors should be taken into account to ensure the correct and most suitable product is selected.
|
||||
|
||||
**Standard vs. Heavy Duty:** The intended use and user weight should dictate whether a standard or heavy-duty gas lift is required. Heavy-duty options, like the one offered by Mastery Mart, are designed to support higher weights and withstand more frequent use 11.
|
||||
|
||||
**Dimensions:** Ensuring the replacement gas lift has the correct dimensions is crucial for compatibility. This includes the overall length, the length of the outer tube, the diameter of both the outer tube and the piston shaft, and the stroke length (the amount of height adjustment the gas lift provides) 8. Some suppliers, like Techly and Mastery Mart, provide detailed measurements to aid in this determination 8.
|
||||
|
||||
**Certifications:** Certifications such as BIFMA, SATRA, BS, EN Standard Class, and SGS indicate that the gas lift has been tested to meet certain safety and quality standards 3. These certifications can provide assurance regarding the product's reliability and durability.
|
||||
|
||||
**Shipping Costs and Delivery Times:** For suppliers located outside of Spain, particularly those in the UK, it is essential to consider the potential shipping costs and delivery times to Spain or other European destinations 1. These factors can significantly impact the overall cost and the time it takes to receive the replacement part.
|
||||
|
||||
**Price vs. Quality:** While price is always a consideration, it is important to balance cost with quality and durability. Investing in a higher-quality gas lift, especially for frequently used chairs, can lead to longer-term cost savings by reducing the need for frequent replacements.
|
||||
|
||||
**Compatibility:** Compatibility with the specific office chair model is a critical factor. Some gas lifts, like those offered by STUA, are designed for their own chairs, ensuring a perfect fit 1. Others, like the Leikurvo and Mastery Mart options, claim wider compatibility with standard office chairs, although Mastery Mart explicitly excludes IKEA chairs 4. Techly even lists compatible chair models for their gas lift 8. Buyers should meticulously review product descriptions and, if feasible, measure their existing gas lift to confirm compatibility. The availability of specific compatibility information from suppliers simplifies the selection process for consumers.
|
||||
|
||||
**Ease of Installation:** For users who plan to replace the gas lift themselves, the ease of installation is an important consideration. Some suppliers, such as Leikurvo and Tincci, specifically mention that their gas lifts are easy to install 4. A user-friendly installation process can save time and effort, especially for individuals without specialized technical skills.
|
||||
|
||||
## **6\. Conclusion and Recommendations**
|
||||
|
||||
The market for standard office chair gas lifts in Spain and Europe presents a range of options catering to different needs and preferences. For individuals requiring replacement gas lifts for specific STUA "Gas Chairs," purchasing directly from STUA Design Shop ensures compatibility, albeit at a potentially higher price point 1. For a broader selection and potentially more affordable options in Spain, Ubuy offers access to brands like Artilife 5.
|
||||
|
||||
Across Europe, Techly provides a budget-friendly option for standard replacements, especially for compatible chair models 8. The Chair Clinic in the UK offers a comprehensive selection of certified gas lifts, along with helpful tools, making them a reliable source, though shipping implications for EU buyers should be considered 3. Proroll, as a German manufacturer, is a strong option for businesses seeking potential bulk orders or customized solutions with a focus on quality and durability 9. Leikurvo, available through Amazon.de, offers a convenient and widely compatible standard replacement with an emphasis on ease of installation 4. Finally, Mastery Mart, via Amazon.co.uk, provides a robust, heavy-duty option with high safety certifications, suitable for more demanding use, but again, shipping to the EU should be considered 11.
|
||||
|
||||
Ultimately, the optimal supplier will depend on the specific requirements of the user, including the type of chair, budget constraints, desired quality and durability, and the urgency of the replacement. There is no single "best" supplier; rather, the ideal choice will align with individual needs and priorities. The European market offers a robust selection of suppliers, indicating a competitive environment that benefits both individual consumers and businesses seeking office chair components. It is recommended that users carefully review product specifications, particularly dimensions, and consider the importance of certifications and customer reviews before making a purchase decision. Comparing prices and factoring in any potential shipping costs will also ensure the most suitable and cost-effective option is chosen.
|
||||
|
||||
#### **Works cited**
|
||||
|
||||
1. GAS CHAIR Gas lift cylinder white – STUA DESIGN SHOP, accessed on March 20, 2025, [https://stua.com/shop/product/gas-chair-gas-lift-cylinder-white/](https://stua.com/shop/product/gas-chair-gas-lift-cylinder-white/)
|
||||
2. Stabilus for Office Furniture \- Ergonomic & Reliable, accessed on March 20, 2025, [https://www.stabilus.com/industries-and-applications/health-recreation-and-furniture/office-furniture](https://www.stabilus.com/industries-and-applications/health-recreation-and-furniture/office-furniture)
|
||||
3. Replacement Office Chair Gas Lifts \- The Chair Clinic Ltd, accessed on March 20, 2025, [https://www.chairclinic.co.uk/office-chair-gas-lifts/](https://www.chairclinic.co.uk/office-chair-gas-lifts/)
|
||||
4. Leikurvo Gas Lift for Office Chair, Total Length 270 mm \- Amazon.de, accessed on March 20, 2025, [https://www.amazon.de/-/en/Leikurvo-Office-Chair-Total-Length/dp/B0CW5KFZ63](https://www.amazon.de/-/en/Leikurvo-Office-Chair-Total-Length/dp/B0CW5KFZ63)
|
||||
5. Heavy Duty Office Chair Gas Lift Cylinder Spain | Ubuy, accessed on March 20, 2025, [https://www.ubuy.com.es/en/product/1PY98SII-artilife-office-chair-gas-lift-cylinder-replacement-heavy-duty-hydraulic-pneumatic-shock-piston-univ](https://www.ubuy.com.es/en/product/1PY98SII-artilife-office-chair-gas-lift-cylinder-replacement-heavy-duty-hydraulic-pneumatic-shock-piston-univ)
|
||||
6. GAS CHAIR Gas lift cylinder black. \- STUA STORE FOR REPLACEMENTS, accessed on March 20, 2025, [https://stua.store/product/gas-chair-gas-lift-cylinder/](https://stua.store/product/gas-chair-gas-lift-cylinder/)
|
||||
7. GAS CHAIR Gas lift cylinder chrome – STUA DESIGN SHOP, accessed on March 20, 2025, [https://stua.com/shop/product/gas-chair-gas-lift-cylinder-chrome/](https://stua.com/shop/product/gas-chair-gas-lift-cylinder-chrome/)
|
||||
8. Gas Lift for Office Chair Adjustable Height Black \- TECHLY, accessed on March 20, 2025, [https://www.techly.com/gas-lift-for-office-chair-adjustable-height-black.html](https://www.techly.com/gas-lift-for-office-chair-adjustable-height-black.html)
|
||||
9. Gas springs✔️ Gas pressure columns✔️ for swivel chairs office ..., accessed on March 20, 2025, [https://proroll.de/en/gas-spring-dampers/](https://proroll.de/en/gas-spring-dampers/)
|
||||
10. proroll GmbH: Wheels & castors \- furniture components for furniture ..., accessed on March 20, 2025, [https://proroll.de/en/](https://proroll.de/en/)
|
||||
11. Stroke, Heavy Duty 1000 lbs, Office Chair Gas Lift Cylinder Replacement, Class 4 (Not for 1KEA, Black), accessed on March 20, 2025, [https://www.amazon.co.uk/Mastery-Mart-Universal-Replacement-Pneumatic/dp/B0859WG3X8](https://www.amazon.co.uk/Mastery-Mart-Universal-Replacement-Pneumatic/dp/B0859WG3X8)
|
||||
12. Office Chair Gas Cylinders \- Wholesale Chair Parts, accessed on March 20, 2025, [https://allchairparts.com/office-chair-gas-cylinders/](https://allchairparts.com/office-chair-gas-cylinders/)
|
||||
13. office chair gas spring, accessed on March 20, 2025, [https://www.tincci.com/swivel-chair-gas-lift/12-office-chair-gas-spring.html](https://www.tincci.com/swivel-chair-gas-lift/12-office-chair-gas-spring.html)
|
||||
@ -1,203 +0,0 @@
|
||||
# **Open Source Resources and Practices for Chair Design**
|
||||
|
||||
**1\. Introduction: The Democratization of Chair Design through Open Source**
|
||||
|
||||
The landscape of furniture design and production is undergoing a significant transformation, with open-source principles gaining considerable traction, particularly in the realm of chair design. This movement signifies a shift towards greater accessibility, customization possibilities, and the fostering of collaborative innovation within the design community. The core idea behind open-source design is the free sharing of design documentation, enabling individuals to create their own versions of products. This approach is proving particularly relevant in furniture, where the confluence of digital fabrication technologies and a burgeoning maker culture is lowering the barriers to entry for both aspiring and established designers 1.
|
||||
|
||||
The increasing availability and affordability of digital fabrication tools, such as CNC routers and laser cutters, have played a pivotal role in the expansion of the open furniture movement. These technologies empower individuals and small workshops to produce furniture pieces from digital designs, making the open-source model not just a theoretical concept but a practical reality. This ease of access to manufacturing capabilities allows for a more distributed approach to production, moving away from traditional, centralized factory models 1. This shift fosters a more inclusive environment where design knowledge and manufacturing capabilities are more widely shared.
|
||||
|
||||
Furthermore, open-source furniture design inherently encourages a departure from conventional mass manufacturing and the associated global shipping networks. Platforms and initiatives in this space often prioritize connecting designers with local makers, establishing more distributed and ethically conscious supply chains. This emphasis on local production not only reduces the environmental impact associated with long-distance transportation but also strengthens local economies and fosters a greater sense of community involvement in the creation of everyday objects 3.
|
||||
|
||||
**2\. Exploring Key Platforms for Open-Source Chair Designs**
|
||||
|
||||
* **2.1. Opendesk: A Global Platform for Local Making**
|
||||
|
||||
Opendesk operates as an online marketplace that serves as a nexus between independent furniture designers and a global network of local makers. This platform facilitates a unique process where customers can browse a variety of furniture designs, including chairs, and then connect with makers in their vicinity to have those designs fabricated. The process typically involves selecting a design, requesting quotes from local makers, choosing a preferred maker based on the quote, and finally receiving the finished furniture directly from the maker within a few weeks 3. This model bypasses the traditional retail infrastructure, eliminating the need for extensive shipping, showrooms, and warehousing.
|
||||
|
||||
While Opendesk hosts a wide array of independently designed furniture, it is important to note that not all designs on the platform may be explicitly licensed under open-source terms that permit free modification and redistribution. Information regarding the specific licensing for each design would likely need to be verified directly on the Opendesk website 3. Furthermore, observations suggest that Opendesk's operational model might be evolving away from a purely open-source approach 5. Nevertheless, the platform's core function of enabling distributed manufacturing through digital design files and local fabrication presents a significant advantage in terms of reducing environmental impact and supporting ethical supply chains 3. By connecting customers directly with local makers, Opendesk fosters a system where furniture is produced on demand, minimizing waste and the carbon footprint associated with traditional furniture distribution 3. The platform also mentions "Designer Collaboration," indicating a space for designers to potentially connect and work together 3.
|
||||
|
||||
* **2.2. AtFAB: Customizable Open-Source Furniture for Distributed Manufacturing**
|
||||
|
||||
AtFAB stands out as a project specifically focused on providing open-source digital files for furniture designs, including a variety of chairs. The central philosophy of AtFAB revolves around empowering individuals to fabricate furniture locally using CNC (Computer Numerical Control) machines. Their website serves as a repository where users can download cut files for various furniture pieces and produce them using locally sourced materials and a nearby CNC machine 4. Since its inception in 2008, AtFAB's model has facilitated a global collective of makers who download these digital files and locally fabricate furniture, demonstrating the power of distributed manufacturing 4.
|
||||
|
||||
A key aspect of AtFAB's design approach is the intention for their furnishings to be fully parametric. This means that the digital design files are created in a way that allows for easy modification of dimensions, material thicknesses, and other details. This adaptability caters to a wide range of user needs and the varying capabilities of different fabrication setups 2. The success of AtFAB underscores the potential of distributed manufacturing as a more inclusive and environmentally responsible method of producing goods. By enabling local fabrication, AtFAB contributes to a less energy-intensive way of making furniture, reducing the need for mass production and global shipping 4. Several open-source chair designs from AtFAB are available with direct download links, such as the 90 Minute Lounge Chair, the 5-30 Minute Chair, and the 90 Minute Sofa 4.
|
||||
|
||||
* **2.3. Obrary: Curated Open Design for CNC Routers**
|
||||
|
||||
Obrary is another platform that offers a collection of designs specifically intended for fabrication using CNC routers. Within their catalog, various furniture pieces, including chairs, are tagged under the designation of "open design" 6. Notable examples of chair designs available on Obrary include the Gustaf Chair and the Alex Chair 6. These designs are listed with a regular price of $0.00 USD, suggesting that they are intended to be freely accessible under an open license 6.
|
||||
|
||||
Obrary explicitly employs Creative Commons licenses for its "open design" furniture offerings. Both the Gustaf Chair and the Alex Chair, for instance, are licensed under a Creative Commons Attribution-ShareAlike 4.0 International License 7. This type of license promotes the sharing and adaptation of the designs, allowing users to download, use, and even modify them, provided they attribute the original creators and share any derivative works under the same license. This commitment to open licensing aligns with the core principles of the open-source movement, encouraging wider use and further development of the designs.
|
||||
|
||||
* **2.4. Other Notable Platforms and Projects**
|
||||
|
||||
Beyond these primary platforms, the open-source furniture ecosystem encompasses a diverse range of other projects and initiatives. Social Furniture, for example, focuses on designs for kitchen and community spaces, utilizing readily available yellow wood sheeting, although the licensing for these designs is not explicitly clear 5. Open Structures represents a different approach, functioning as a database of open-source parts and complete designs that can be combined and adapted to create various furniture pieces 5. These examples illustrate the breadth of the open-source furniture movement, with different projects often focusing on specific types of furniture, materials, or community needs, reflecting a dynamic and evolving landscape 5.
|
||||
|
||||
**3\. Repositories of Open-Source Chair Design Files**
|
||||
|
||||
* **3.1. Thingiverse and YouMagine: User-Generated 3D Printable Designs**
|
||||
|
||||
Thingiverse and YouMagine are prominent online repositories that host a vast collection of user-generated designs primarily intended for 3D printing. Within these platforms, a significant number of furniture projects, including a diverse array of chair designs, can be found 5. Examples of chair-related projects include the Space Frame Stools, which draw inspiration from NASA space equipment 5, the Layer Stool 5, and a fully functional 3D printed stool designed to be produced on a desktop 3D printer without the need for supports or post-printing assembly 11.
|
||||
|
||||
The open nature of these platforms encourages a culture of remixing and adaptation, where users can take existing designs as a starting point and modify them to suit their own needs or creative visions. This collaborative environment fosters innovation and the continuous improvement of designs within the community 12. While Thingiverse and YouMagine offer a wide spectrum of chair designs, the licensing terms for these projects can vary significantly. Users are advised to carefully review the specific license associated with each design to understand the permissions granted for use, modification, and redistribution 9.
|
||||
|
||||
A notable example of a complex, open-source chair design available on YouMagine is the Puzzle Chair by Joris Laarman Lab 13. This chair is designed to be assembled from numerous 3D-printed parts that fit together like a three-dimensional puzzle. While some versions of the Makerchair series, which includes the Puzzle Chair, are available under a Creative Commons license, allowing for download and production, they might have non-commercial restrictions, meaning adaptation of the design might not be permitted 18. Nevertheless, the Puzzle Chair serves as a compelling illustration of the potential for creating intricate and functional furniture using 3D printing technologies and open-source principles.
|
||||
|
||||
* **3.2. GitHub: Collaborative Open-Source Projects and Design Files**
|
||||
|
||||
GitHub, primarily known as a platform for hosting and collaborating on software development projects, also serves as a repository for a variety of other open-source endeavors, including furniture designs. The platform's version control system and collaborative features make it well-suited for projects where designers and makers can work together on developing and refining designs. One example of a GitHub-hosted project is steiza/open\_source\_furniture, which provides code for generating instructions for a CNC machine to create custom-sized kitchen chairs 20. This project utilizes OpenSCAD, a free software for creating solid 3D CAD objects, and requires some technical familiarity with code and CNC processes.
|
||||
|
||||
Another notable example is the Maslow Folding chair, for which open-source design files are available on GitHub 21. This project, developed in collaboration with the Peremoha Center and KNUCA Lab, involves furniture designs crafted using CNC milling machines, with the folding chair being made from plywood. While the GitHub repository link was inaccessible at the time of research 22, the project itself exemplifies a community-driven effort to share design files for replication and potential modification. Projects hosted on GitHub often cater to a more technically inclined audience comfortable with navigating code repositories and potentially contributing to the development of the designs.
|
||||
|
||||
* **3.3. Direct Download Links from Projects**
|
||||
|
||||
In addition to centralized repositories, many open-source furniture projects offer direct download links to their design files directly from their own websites. A prime example of this is AtFAB, which provides downloadable files for all its open-source furniture designs, including chairs, directly on its website 4. This approach offers a straightforward way for users to access the design files, often accompanied by project-specific documentation, assembly instructions, and information about the materials and tools required for fabrication. Direct downloads can be particularly convenient for users who are already familiar with a specific project or designer and prefer a more direct access method compared to browsing through large repositories.
|
||||
|
||||
**4\. Open-Source Software for Chair Design**
|
||||
|
||||
* **4.1. SketchChair: Parametric Chair Design for Digital Fabrication**
|
||||
|
||||
SketchChair is a free and open-source software tool specifically developed to enable anyone to easily design and build their own digitally fabricated furniture, with a particular focus on chairs 23. This innovative software empowers users to create unique, personalized chair designs through a simple 2D drawing interface. The software then automatically generates the structural components of the chair and even tests its stability through a built-in physics engine 26. A key feature of SketchChair is its parametric design capability, which means that the software uses mathematical relationships to define the geometry of the chair, allowing for easy adjustments and customizations 23.
|
||||
|
||||
SketchChair simplifies the process of designing for digital fabrication by automatically generating the necessary cutting profiles for various digital fabrication machines like CNC routers, laser cutters, and even paper cutters 26. These profiles can then be used to cut the chair parts from flat sheet materials, which can typically be assembled by hand 26. The software also includes features like 3D visualization, material library options, and the ability to export designs in various formats suitable for CNC machines (e.g., DXF) 23. Furthermore, SketchChair fosters a strong sense of community through its online design library, accessible via the SketchChair website, where users can upload, share, download, and modify chair designs 25. This collaborative aspect allows chair designs to evolve as users continually refine and adapt them 25. While the main SketchChair website has experienced periods of unavailability 5, the project's open-source nature means that the software and its documentation are also available on platforms like GitHub under the GPL-3.0 license 24. The GitHub repository provides access to the software's code, documentation, and issue tracker, allowing for community contributions and support 24.
|
||||
|
||||
* **4.2. Sweet Home 3D: Free Interior Design Software with Furniture Modeling**
|
||||
|
||||
Sweet Home 3D is a free and open-source interior design application that provides users with the tools to draw house plans, arrange furniture within those plans, and visualize the results in 3D 28. While not exclusively focused on chair design, Sweet Home 3D includes a catalog of furniture models that can be used in interior layouts, and it also offers the capability for users to import or even create their own custom furniture models, including chairs 28. The software boasts a user-friendly interface, making it accessible to individuals who may not have extensive experience with complex CAD software 29.
|
||||
|
||||
Sweet Home 3D is distributed under the GNU General Public License, emphasizing its open-source nature 28. This licensing allows users to freely use, distribute, and even modify the software. The application comes with a library of over 1,600 3D models and 400 textures, which can be readily used in design projects 28. While its primary focus is on interior layout and visualization, Sweet Home 3D can be a valuable tool for individuals looking to design and plan the integration of chairs within a broader living space, or for creating basic 3D models of furniture.
|
||||
|
||||
* **4.3. Other Relevant Open-Source CAD Tools**
|
||||
|
||||
Beyond SketchChair and Sweet Home 3D, a variety of other open-source CAD (Computer-Aided Design) software tools could potentially be utilized for chair design, although they may not be explicitly mentioned in the provided research snippets. Examples of such tools include FreeCAD and Blender. FreeCAD is a general-purpose parametric 3D CAD modeler that is well-suited for designing precise and complex objects, including furniture. Blender, while primarily known for its capabilities in 3D modeling, sculpting, animation, and rendering, can also be used for creating detailed 3D models of chairs. These tools often offer a wider range of features and customization options compared to software specifically focused on furniture design, but they may also come with a steeper learning curve. The choice of software ultimately depends on the user's specific needs, technical skills, and the desired level of design complexity.
|
||||
|
||||
* **Table 1: Comparison of Open-Source Chair Design Software**
|
||||
|
||||
| Software Name | License | Key Features | Ease of Use | Community/Design Library | Target User |
|
||||
| :---- | :---- | :---- | :---- | :---- | :---- |
|
||||
| SketchChair | GPL-3.0 | Parametric design, 3D visualization, CNC export, stability testing | Potentially steeper learning curve for advanced features | Yes | Makers, digital fabrication enthusiasts |
|
||||
| Sweet Home 3D | GNU General Public License | Interior design, furniture arrangement, basic 3D modeling, large library | User-friendly interface | Limited for custom design | Interior designers, DIYers |
|
||||
|
||||
**5\. DIY Chair Design Guides and Plans**
|
||||
|
||||
* **5.1. Websites Offering Free Chair Plans**
|
||||
|
||||
For individuals interested in building their own chairs without necessarily engaging in digital fabrication, numerous websites offer free woodworking plans and guides. Platforms like Ana White, Woodshop Diaries, Instructables, and MyOutdoorPlans are popular resources for DIY enthusiasts seeking step-by-step instructions for a wide variety of furniture projects, including chairs 30. These websites often feature plans for various chair types, catering to different needs and skill levels.
|
||||
|
||||
Ana White, for instance, provides a collection of free plans for modern outdoor chairs using readily available lumber like 2x4s and 2x6s, often emphasizing beginner-friendly construction 32. Woodshop Diaries offers plans for simple yet stylish outdoor chairs, often incorporating dowel rails for a modern aesthetic, complete with diagrams, dimensions, and video tutorials 31. Instructables is a broad platform where users share DIY projects of all kinds, including numerous chair designs, such as the ZipStich Chair, which utilizes a unique zip-tie construction method 36. MyOutdoorPlans focuses on outdoor furniture and provides detailed woodworking plans for various chair designs, including a basic wood chair suitable for dining 33. While these plans are typically offered for free personal use, it's important to note that they may not always be under a fully open-source license that allows for modification and redistribution of the plans themselves.
|
||||
|
||||
* **5.2. Focus on Different Construction Methods and Skill Levels**
|
||||
|
||||
The chair plans available on these DIY websites showcase a diverse range of construction methods, accommodating users with varying skill levels and access to different tools. Many plans rely on fundamental woodworking techniques using screws and glue for assembly 31. Pocket hole joinery, which creates strong and concealed joints, is also a popular method featured in plans on websites like Woodshop Diaries and Ana White 31. For those seeking more unconventional approaches, Instructables features projects like the ZipStich Chair, which demonstrates how plywood pieces can be "stitched" together using zip ties to create a functional chair 36. This variety in construction methods allows individuals to select projects that align with their existing skills, the tools they have available, and the desired aesthetic and structural integrity of the final piece.
|
||||
|
||||
* **5.3. Examples of Various Chair Types**
|
||||
|
||||
The range of chair types for which free plans are readily available is quite extensive, catering to a multitude of needs and preferences. Adirondack chairs, known for their comfortable, reclined design, are a popular choice for outdoor spaces, and plans for both classic and modern interpretations can be found on websites like Kreg Tool, Ana White, and Pinterest 30. Modern outdoor chairs with clean lines and simple construction are also well-represented, with resources available on Woodshop Diaries and Ana White 31. For situations where portability and space-saving are important, plans for folding chairs, such as the Maslow Folding chair mentioned on TOLOCAR and Ana White, can be found 21. Even rocking chairs, offering a relaxing seating option, have open-source plans available, as seen with the Oval Rocker DIY plans by Andrew Doxtater and the Rok-Bak Chair mentioned on Shareable 35. This wide array of chair types with accessible plans highlights the vibrancy of the DIY furniture movement and provides ample options for individuals looking to build their own seating solutions.
|
||||
|
||||
**6\. Best Practices in Ergonomic Chair Design**
|
||||
|
||||
* **6.1. Key Ergonomic Principles for Comfort and Support**
|
||||
|
||||
Ergonomic chair design focuses on optimizing human well-being and overall system performance by considering the interaction between individuals and their environment or tools. In the context of a chair, this translates to creating seating that promotes a natural posture, provides adequate support to the spine, and minimizes strain on muscles and joints, especially during prolonged periods of sitting 39. Adhering to ergonomic principles is crucial for long-term comfort, preventing musculoskeletal disorders, and enhancing productivity 41. These principles are applicable not only to office chairs but also to any type of chair intended for extended use.
|
||||
|
||||
* **6.2. Adjustability, Lumbar Support, Seat Dimensions, and Posture**
|
||||
|
||||
Several key features contribute to an ergonomic chair design. Adjustability is paramount, allowing users to customize the chair's settings to their individual body dimensions and preferences. This includes the ability to adjust the seat height so that the feet rest flat on the floor and the thighs are parallel to the ground 40. Seat depth adjustment ensures that there is adequate thigh support without putting pressure on the back of the knees 39. Lumbar support, which follows the natural inward curve of the lower back, is essential for maintaining spinal alignment and preventing slouching 39. The height and sometimes the depth of the lumbar support should also be adjustable to fit different users 45. Armrests, if present, should be adjustable in height and width to allow the shoulders to relax and the elbows to stay close to the body 40. Maintaining proper posture while seated is also critical, with the hips slightly higher than the knees, the forearms parallel to the floor when typing, and the monitor positioned at eye level to avoid neck strain 39.
|
||||
|
||||
* **6.3. Insights from Ergonomic Guidelines and Academic Research**
|
||||
|
||||
Various guidelines and academic research provide further insights into optimal ergonomic chair design. Organizations like Harvard GSE, Mayo Clinic, University of Pittsburgh, and CCOHS offer practical tips and criteria for selecting and adjusting ergonomic chairs for office environments 39. Academic studies delve deeper into the science behind seated comfort, highlighting the importance of factors like pressure distribution across the seat and backrest 48 and the natural movements of the body while sitting 49. Research also explores the application of ergonomic principles in specific contexts, such as the design of chairs for cobblers to mitigate musculoskeletal disorders 43 or the development of ergonomically optimized chairs for classroom use to improve student comfort and concentration 44. These resources underscore the fact that ergonomic design is not a one-size-fits-all approach and should consider the specific needs and tasks of the user.
|
||||
|
||||
**7\. Principles of Structural Integrity in Chair Design**
|
||||
|
||||
* **7.1. Material Selection for Strength and Durability**
|
||||
|
||||
The selection of appropriate materials is fundamental to ensuring the structural integrity, strength, and durability of a chair 42. The intended use of the chair, the expected load it will bear, and the environmental conditions it will be exposed to should all factor into the material choice. Common materials for chair construction include solid wood, which offers strength and aesthetic appeal; plywood, which provides stability and can be easily shaped; metal, known for its robustness; and even 3D printing filaments, which allow for complex geometries 42. For outdoor chairs, materials with inherent weather resistance, such as cedar 31, or those that are treated to withstand moisture and UV exposure are crucial. In environments where corrosion might be a concern, such as areas exposed to moisture, plastic chairs, like those used in concrete construction for rebar support, can be a suitable option due to their non-corrosive nature 51. The choice of material directly influences the chair's ability to withstand static loads (like the weight of a person sitting) and dynamic loads (like movement while sitting) without deformation or failure 50.
|
||||
|
||||
* **7.2. Joinery Techniques and Structural Balance Considerations**
|
||||
|
||||
The techniques used to join the various parts of a chair are critical for its structural integrity 42. Common joinery methods include using screws and glue, which is straightforward for many DIY projects 31; employing dowels for added strength and alignment; utilizing mortise and tenon joints, which offer robust connections; and even more modern methods like pocket hole joinery for concealed and strong joints 31. Beyond the specific joinery method, considering the overall structural balance of the chair is essential. Structural balance involves ensuring that the forces acting on the chair are in equilibrium to prevent tipping, sagging, or other forms of failure 52. For instance, the tilting point of a chair should ideally be located directly beneath the combined center of gravity of the chair and the person sitting in it 52. In designs like rocking chairs, the dynamic forces created by the rocking motion need to be carefully considered, and structural bracing may be necessary to ensure stability and longevity 52.
|
||||
|
||||
* **7.3. Load Analysis and Stability Factors**
|
||||
|
||||
Load analysis involves understanding the forces that will act upon a chair during its use. This includes both static loads, such as the weight of the person sitting, and dynamic loads, which arise from movements while seated 50. Chairs must be designed to withstand these loads without undergoing permanent deformation or structural failure. Several factors contribute to the overall stability of a chair. The design of the base is crucial; for example, a five-point base is generally recommended for office chairs as it provides greater stability compared to a four-point base 46. The distribution of weight across the chair's structure also plays a significant role in its stability. A well-designed chair will distribute the load evenly across its components, minimizing stress on any single point. In some cases, especially for tall or narrow furniture, it may be necessary to secure the piece to a floor or wall to prevent tipping 52. Understanding these principles of load analysis and stability is vital for creating chairs that are not only comfortable but also safe and durable for their intended use.
|
||||
|
||||
**8\. Open-Source Furniture Design Communities and Collaboration**
|
||||
|
||||
* **8.1. Online Forums and Groups**
|
||||
|
||||
The open-source furniture design movement is supported by a vibrant network of online communities where enthusiasts, makers, and designers can connect, share ideas, and seek assistance. Online forums, such as the Opendesk Community Forum on Google Groups, provide dedicated spaces for discussions specifically related to open-source furniture projects and their fabrication 54. Platforms like Reddit also host numerous subreddits relevant to furniture design and making, including r/Carpentry, r/woodworking, and r/DIY, where users can share their projects, ask questions, and exchange resources related to open-source designs 55. These online spaces serve as valuable hubs for learning, troubleshooting, and fostering a sense of community among individuals interested in open-source furniture.
|
||||
|
||||
* **8.2. Collaborative Platforms like O-LAP for Parametric Design**
|
||||
|
||||
O-LAP (Open-source Living and Architectural Prototypes) represents a more structured approach to open-source collaboration in furniture design, with a particular emphasis on parametric design 56. This community-run platform provides a framework for designers to create parametric furniture designs as plugins. The platform leverages open-source web technologies, including JavaScript and Git, to facilitate a decentralized and collaborative design process. Designers maintain ownership of their designs as public Git repositories, and they can contribute to the main O-LAP web app by submitting pull requests. Community moderators play a role in ensuring that submitted designs adhere to the platform's standards. Users can then access these designs through a web interface, customize them based on the designer's enabled parameters, and extract CAD drawings for digital fabrication. O-LAP's model promotes transparency, with the design narrative and contributions of collaborators recorded at each step, fostering an environment of open collaboration and the evolution of designs through replication and forking 56.
|
||||
|
||||
* **8.3. The Role of Maker Spaces and Shared Design Initiatives**
|
||||
|
||||
Maker spaces play a crucial role in the open-source furniture movement by providing individuals with access to the tools, equipment, and shared knowledge necessary to bring digital designs to life. These community-based workshops often host CNC routers, laser cutters, 3D printers, and traditional woodworking tools, making digital fabrication accessible to a wider audience. Shared design initiatives, such as Wikiblock, offered by the Better Block Foundation, further contribute to community involvement in open-source furniture design 58. Wikiblock provides a database of open-source blueprints for neighborhood fixtures like benches and bus stops, which can be downloaded, fabricated in a maker space, and assembled by hand, empowering communities to enhance their own public spaces with minimal cost and effort. Similarly, open design contests, like the one mentioned by Shareable, encourage the creation and sharing of furniture designs that can be made using digital fabrication, often under Creative Commons licenses 38. These initiatives highlight the potential of open-source design to foster creativity, collaboration, and community-driven solutions for furniture needs.
|
||||
|
||||
**9\. Conclusion: Embracing Open Source in Chair Design and Making**
|
||||
|
||||
The world of chair design is increasingly embracing the principles of open source, offering a wealth of resources for individuals interested in creating their own seating solutions. From comprehensive platforms like Opendesk and AtFAB to vast repositories like Thingiverse and YouMagine, a multitude of designs and digital files are readily available. Open-source software tools such as SketchChair and Sweet Home 3D further empower users to conceptualize and model their own chair designs, while numerous websites provide free, step-by-step plans for traditional woodworking methods.
|
||||
|
||||
Understanding the best practices in ergonomic design and the fundamental principles of structural integrity are crucial for creating chairs that are not only aesthetically pleasing but also comfortable and durable. Furthermore, the vibrant ecosystem of online forums, collaborative platforms like O-LAP, and the supportive environment of maker spaces foster a strong sense of community and shared learning within the open-source furniture movement. As digital fabrication technologies continue to advance and the spirit of collaboration thrives, the future of open-source chair design holds immense potential for innovation, accessibility, and the democratization of furniture creation.
|
||||
|
||||
#### **Works cited**
|
||||
|
||||
1. FABrics: Open Source Furniture \- Core77, accessed on March 20, 2025, [https://www.core77.com/projects/51537/FABrics-Open-Source-Furniture](https://www.core77.com/projects/51537/FABrics-Open-Source-Furniture)
|
||||
2. Open CNC Furniture \- Make Magazine, accessed on March 20, 2025, [https://makezine.com/article/workshop/woodworking/open-source-furniture-2/](https://makezine.com/article/workshop/woodworking/open-source-furniture-2/)
|
||||
3. Opendesk: Furniture designed for inspiring workplaces, accessed on March 20, 2025, [https://www.opendesk.cc/](https://www.opendesk.cc/)
|
||||
4. AtFAB Open Source Furniture \- Filson & Rohrbacher, accessed on March 20, 2025, [https://filson-rohrbacher.com/work/atfab](https://filson-rohrbacher.com/work/atfab)
|
||||
5. Open Source Furniture | tiefpunkt's notes, accessed on March 20, 2025, [https://notes.tiefpunkt.com/projects/open-source-furniture.html](https://notes.tiefpunkt.com/projects/open-source-furniture.html)
|
||||
6. Designs for the CNC Router – tagged "open design" – Obrary, accessed on March 20, 2025, [https://obrary.com/collections/designs-for-the-cnc-router/open-design](https://obrary.com/collections/designs-for-the-cnc-router/open-design)
|
||||
7. Gustaf Chair – Obrary, accessed on March 20, 2025, [https://obrary.com/products/gustaf-chair](https://obrary.com/products/gustaf-chair)
|
||||
8. Alex Chair \- the living hinge chair \- Obrary, accessed on March 20, 2025, [https://obrary.com/products/alex-chair](https://obrary.com/products/alex-chair)
|
||||
9. Space Frame Stools BWarDesign. by bwardesign \- Thingiverse, accessed on March 20, 2025, [https://www.thingiverse.com/thing:32861](https://www.thingiverse.com/thing:32861)
|
||||
10. Layer Stool by \- Thingiverse, accessed on March 20, 2025, [https://www.thingiverse.com/thing:32036](https://www.thingiverse.com/thing:32036)
|
||||
11. Full Size 100% 3D Printed Stool by The\_OS \- Thingiverse, accessed on March 20, 2025, [https://www.thingiverse.com/thing:2929494](https://www.thingiverse.com/thing:2929494)
|
||||
12. Siri, Print Me A Chair | Year of Open Source, accessed on March 20, 2025, [https://yearofopensource.net/siri-print-me-a-chair.html](https://yearofopensource.net/siri-print-me-a-chair.html)
|
||||
13. Ultimaker and Joris Laarman Lab 3D Print a Chair to Solve the Ultimate Design Puzzle, accessed on March 20, 2025, [https://3dprintingindustry.com/news/ultimaker-joris-laarman-lab-3d-print-chair-solve-ultimate-design-puzzle-34928/](https://3dprintingindustry.com/news/ultimaker-joris-laarman-lab-3d-print-chair-solve-ultimate-design-puzzle-34928/)
|
||||
14. Cooper Hewitt, Smithsonian Design Museum to Present" Joris Laarman Lab: Design in the Digital Age", accessed on March 20, 2025, [https://www.si.edu/newsdesk/releases/cooper-hewitt-smithsonian-design-museum-present-joris-laarman-lab-design-digital-age](https://www.si.edu/newsdesk/releases/cooper-hewitt-smithsonian-design-museum-present-joris-laarman-lab-design-digital-age)
|
||||
15. Joris Laarman opens first major solo show at the Groninger Museum \- Dezeen, accessed on March 20, 2025, [https://www.dezeen.com/2015/11/26/joris-laarman-solo-show-groninger-museum-netherlands/](https://www.dezeen.com/2015/11/26/joris-laarman-solo-show-groninger-museum-netherlands/)
|
||||
16. Makerchairs \- Joris Laarman, accessed on March 20, 2025, [https://www.jorislaarman.com/work/makechairs/](https://www.jorislaarman.com/work/makechairs/)
|
||||
17. Joris Laarman Maker Chair: Assemble Your Furniture Using 3D Printed Fragments, accessed on March 20, 2025, [https://parametric-architecture.com/joris-laarman-maker-chair/](https://parametric-architecture.com/joris-laarman-maker-chair/)
|
||||
18. 3D-printed open source chair in the Rijksmuseum, accessed on March 20, 2025, [https://waag.org/en/article/3d-printed-open-source-chair-rijksmuseum/](https://waag.org/en/article/3d-printed-open-source-chair-rijksmuseum/)
|
||||
19. Designs in collection "Chairs" \- YouMagine, accessed on March 20, 2025, [https://youmagine.com/collections/chairs](https://youmagine.com/collections/chairs)
|
||||
20. steiza/open\_source\_furniture: Ever want to build your own furniture, but weren't sure where to start? Start here\! \- GitHub, accessed on March 20, 2025, [https://github.com/steiza/open\_source\_furniture](https://github.com/steiza/open_source_furniture)
|
||||
21. Making furniture from plywood \- Tolocar Project, accessed on March 20, 2025, [https://tolocar.org/en/interventions/45-furniture-drawings-Ostriv/](https://tolocar.org/en/interventions/45-furniture-drawings-Ostriv/)
|
||||
22. accessed on January 1, 1970, [https://github.com/maslowcommunitygarden/fold-flat-chair](https://github.com/maslowcommunitygarden/fold-flat-chair)
|
||||
23. SketchChair Pricing, Features, and Reviews (Mar 2025\) \- SoftwareSuggest, accessed on March 20, 2025, [https://www.softwaresuggest.com/sketchchair](https://www.softwaresuggest.com/sketchchair)
|
||||
24. DiatomStudio/SketchChair: SketchChair is a free, open ... \- GitHub, accessed on March 20, 2025, [https://github.com/DiatomStudio/SketchChair](https://github.com/DiatomStudio/SketchChair)
|
||||
25. SketchChair by Diatom Studio, accessed on March 20, 2025, [http://www.sketchchair.cc/](http://www.sketchchair.cc/)
|
||||
26. SKETCH CHAIR \- viennaopen, accessed on March 20, 2025, [http://2012.viennaopen.net/en/sketch-chair\_diatom/index.html](http://2012.viennaopen.net/en/sketch-chair_diatom/index.html)
|
||||
27. SketchChair Reviews in 2025 \- SourceForge, accessed on March 20, 2025, [https://sourceforge.net/software/product/SketchChair/](https://sourceforge.net/software/product/SketchChair/)
|
||||
28. Sweet Home 3D \- Discover 3D Home Design, accessed on March 20, 2025, [https://www.sweethome3d.com/](https://www.sweethome3d.com/)
|
||||
29. 10 Best Free Furniture Design Software of 2025 \- Foyr, accessed on March 20, 2025, [https://foyr.com/learn/best-free-furniture-design-software](https://foyr.com/learn/best-free-furniture-design-software)
|
||||
30. DIY Adirondack Chair \- How To Build an Adirondack Chair \- Kreg Tool, accessed on March 20, 2025, [https://learn.kregtool.com/plans/adirondack-chair/](https://learn.kregtool.com/plans/adirondack-chair/)
|
||||
31. How to Make a Simple Chair \--FREE BUILDING PLANS\! \- Woodshop Diaries, accessed on March 20, 2025, [https://www.woodshopdiaries.com/how-to-make-a-diy-outdoor-chair/](https://www.woodshopdiaries.com/how-to-make-a-diy-outdoor-chair/)
|
||||
32. 30+ FREE Outdoor Chair Plans | Ana White, accessed on March 20, 2025, [https://www.ana-white.com/node/89536](https://www.ana-white.com/node/89536)
|
||||
33. Wood Chair Plans \- MyOutdoorPlans, accessed on March 20, 2025, [https://myoutdoorplans.com/furniture/wood-chair-plans/](https://myoutdoorplans.com/furniture/wood-chair-plans/)
|
||||
34. 25 Free DIY Outdoor Chair Plans for Lawn, Patio and Garden \- Pinterest, accessed on March 20, 2025, [https://www.pinterest.com/pin/25-free-diy-outdoor-chair-plans-for-lawn-patio-and-garden--350436414769943953/](https://www.pinterest.com/pin/25-free-diy-outdoor-chair-plans-for-lawn-patio-and-garden--350436414769943953/)
|
||||
35. OVAL ROCKER DIY PLANS by Andrew Doxtater, accessed on March 20, 2025, [https://www.andrewdoxtater.com/work/ovalrockerdiy](https://www.andrewdoxtater.com/work/ovalrockerdiy)
|
||||
36. HomeMade Modern DIY the ZipStich Chair : 10 Steps (with Pictures) \- Instructables, accessed on March 20, 2025, [https://www.instructables.com/HomeMade-Modern-DIY-The-ZipStich-Chair/](https://www.instructables.com/HomeMade-Modern-DIY-The-ZipStich-Chair/)
|
||||
37. 20 open source furniture designs that you can make yourself \- Pinterest, accessed on March 20, 2025, [https://www.pinterest.com/pin/373376625342581716/](https://www.pinterest.com/pin/373376625342581716/)
|
||||
38. 20 open source furniture designs that you can make yourself \- Shareable, accessed on March 20, 2025, [https://www.shareable.net/20-open-source-furniture-designs/](https://www.shareable.net/20-open-source-furniture-designs/)
|
||||
39. Ergonomics | Operations \- Harvard Graduate School of Education, accessed on March 20, 2025, [https://operations.gse.harvard.edu/planninganddesign/ergonomics](https://operations.gse.harvard.edu/planninganddesign/ergonomics)
|
||||
40. Office ergonomics: Your how-to guide \- Mayo Clinic, accessed on March 20, 2025, [https://www.mayoclinic.org/healthy-lifestyle/adult-health/in-depth/office-ergonomics/art-20046169](https://www.mayoclinic.org/healthy-lifestyle/adult-health/in-depth/office-ergonomics/art-20046169)
|
||||
41. Creating an Ergonomic Workspace: OFW's Tips and Best Practices, accessed on March 20, 2025, [https://www.officefurniturewarehouse.co.nz/blogs/news/creating-an-ergonomic-workspace-ofw-s-tips-and-best-practices](https://www.officefurniturewarehouse.co.nz/blogs/news/creating-an-ergonomic-workspace-ofw-s-tips-and-best-practices)
|
||||
42. Creating Your Own Ergonomic Office Chair: A Step-by-Step Guide \- Sihoo, accessed on March 20, 2025, [https://de.sihoooffice.com/blogs/bloggen/creating-your-own-ergonomic-office-chair-a-step-by-step-guide](https://de.sihoooffice.com/blogs/bloggen/creating-your-own-ergonomic-office-chair-a-step-by-step-guide)
|
||||
43. Ergonomic Chair Design as a Solution to Musculoskeletal Disorders among Traditional Cobblers: An Anthropometric Study | IIETA, accessed on March 20, 2025, [https://www.iieta.org/journals/jesa/paper/10.18280/jesa.560419](https://www.iieta.org/journals/jesa/paper/10.18280/jesa.560419)
|
||||
44. (PDF) Ergonomically Optimized Chair: Design and Cost Analysis \- ResearchGate, accessed on March 20, 2025, [https://www.researchgate.net/publication/383458410\_Ergonomically\_Optimized\_Chair\_Design\_and\_Cost\_Analysis](https://www.researchgate.net/publication/383458410_Ergonomically_Optimized_Chair_Design_and_Cost_Analysis)
|
||||
45. How to Choose an Ergonomic Chair | Office of Public Safety & Emergency Management, accessed on March 20, 2025, [https://www.safety.pitt.edu/ehs/ergonomics/how-choose-ergonomic-chair](https://www.safety.pitt.edu/ehs/ergonomics/how-choose-ergonomic-chair)
|
||||
46. Office Ergonomics \- Ergonomic Chair \- CCOHS, accessed on March 20, 2025, [https://www.ccohs.ca/oshanswers/ergonomics/office/chair.html](https://www.ccohs.ca/oshanswers/ergonomics/office/chair.html)
|
||||
47. Ergonomic Chairs | Research, Economic Engagement and Outreach \- University of New Hampshire, accessed on March 20, 2025, [https://www.unh.edu/research/research/complianceehs/environmental-health-safety/occupational-safety/ergonomics/ergonomic-chairs](https://www.unh.edu/research/research/complianceehs/environmental-health-safety/occupational-safety/ergonomics/ergonomic-chairs)
|
||||
48. The Art and Science of Pressure Distribution \- Research \- Herman Miller, accessed on March 20, 2025, [https://www.hermanmiller.com/research/categories/white-papers/the-art-and-science-of-pressure-distribution/](https://www.hermanmiller.com/research/categories/white-papers/the-art-and-science-of-pressure-distribution/)
|
||||
49. The Kinematics of Sitting \- Research \- Herman Miller, accessed on March 20, 2025, [https://www.hermanmiller.com/research/categories/white-papers/the-kinematics-of-sitting/](https://www.hermanmiller.com/research/categories/white-papers/the-kinematics-of-sitting/)
|
||||
50. Structural Design and Ergonomics in Home Furnishings \- I-MAS, accessed on March 20, 2025, [https://i-mas.com/en/structural-design-and-ergonomics-in-home-furnishings/](https://i-mas.com/en/structural-design-and-ergonomics-in-home-furnishings/)
|
||||
51. Chairs in Concrete Construction: A Crucial Element for Structural Integrity, accessed on March 20, 2025, [https://alsyedconstruction.com/chairs-in-concrete-construction-a-crucial-element-for-structural-integrity/](https://alsyedconstruction.com/chairs-in-concrete-construction-a-crucial-element-for-structural-integrity/)
|
||||
52. Structural Design Principles | Machine Workshop, accessed on March 20, 2025, [https://ms-kb.msd.unimelb.edu.au/machine-workshop/making/step-by-step/designing/designing-for-making/structural-design-principles](https://ms-kb.msd.unimelb.edu.au/machine-workshop/making/step-by-step/designing/designing-for-making/structural-design-principles)
|
||||
53. Design a Chair that Fits like a Glove \- FineWoodworking, accessed on March 20, 2025, [https://www.finewoodworking.com/project-guides/chairs-benches-and-stools/design-a-chair-that-fits-like-a-glove](https://www.finewoodworking.com/project-guides/chairs-benches-and-stools/design-a-chair-that-fits-like-a-glove)
|
||||
54. Opendesk Community Forum \- Google Groups, accessed on March 20, 2025, [https://groups.google.com/g/opendesk-community](https://groups.google.com/g/opendesk-community)
|
||||
55. Open Source Furniture Designs : r/Carpentry \- Reddit, accessed on March 20, 2025, [https://www.reddit.com/r/Carpentry/comments/7ys9ra/open\_source\_furniture\_designs/](https://www.reddit.com/r/Carpentry/comments/7ys9ra/open_source_furniture_designs/)
|
||||
56. O-LAP/home: Community for parametric furniture designs. \- GitHub, accessed on March 20, 2025, [https://github.com/O-LAP/home](https://github.com/O-LAP/home)
|
||||
57. Parametric Furniture: O-LAP, accessed on March 20, 2025, [https://o-lap.org/](https://o-lap.org/)
|
||||
58. Open-Source Community Furniture Projects : wikiblock \- Trend Hunter, accessed on March 20, 2025, [https://www.trendhunter.com/trends/wikiblock](https://www.trendhunter.com/trends/wikiblock)
|
||||
BIN
products/poly-mech/cad/chairs/resources/se_The_Art_and_Science_of_Pressure_Distribution.pdf
(Stored with Git LFS)
BIN
products/poly-mech/cad/chairs/resources/se_The_Art_and_Science_of_Pressure_Distribution.pdf
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/drawers/500/explode.jpg
(Stored with Git LFS)
BIN
products/poly-mech/cad/drawers/500/explode.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/drawers/500/perspective.jpg
(Stored with Git LFS)
BIN
products/poly-mech/cad/drawers/500/perspective.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/drawers/600/10/600-10-Single.step
(Stored with Git LFS)
BIN
products/poly-mech/cad/drawers/600/10/600-10-Single.step
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/drawers/600/explode.jpg
(Stored with Git LFS)
BIN
products/poly-mech/cad/drawers/600/explode.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/drawers/600/perspective.jpg
(Stored with Git LFS)
BIN
products/poly-mech/cad/drawers/600/perspective.jpg
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
products/poly-mech/cad/drawers/tools/box_folding_tool.png
(Stored with Git LFS)
BIN
products/poly-mech/cad/drawers/tools/box_folding_tool.png
(Stored with Git LFS)
Binary file not shown.
@ -1,348 +0,0 @@
|
||||
// Customizable parameters for the box folding tool
|
||||
// These values are based on the provided screenshot.
|
||||
|
||||
// Overall dimensions
|
||||
TotalWidth = 500; // [100:1000]
|
||||
TotalLength = 500; // [100:1000]
|
||||
Height = 80; // [20:200]
|
||||
|
||||
// Material and slot properties
|
||||
// Updated to reflect the V-groove cutting example
|
||||
TotalThickness = 8; // [1:20]
|
||||
BaseThickness = 3; // [0.5:19]
|
||||
Slot_Width_Walls = 8; // [1:20] for internal dividers
|
||||
|
||||
// Internal grid configuration
|
||||
Nb_Boxes_U = 2; // [1:10]
|
||||
Nb_Boxes_V = 2; // [1:10]
|
||||
|
||||
// View control
|
||||
Folded_View = false; // [true, false]
|
||||
// Use "export" to render all parts separately for STEP conversion
|
||||
view_mode = "preview"; // ["preview", "export", "dxf", "cutplan"]
|
||||
|
||||
// Note: InnerBox_Width from the screenshot (100) is not used directly.
|
||||
// Instead, the compartment widths are calculated based on TotalWidth, Height, and Nb_Boxes_U/V.
|
||||
// This ensures the design remains consistent with the overall dimensions.
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Main module to generate the box folding pattern
|
||||
// ---------------------------------------------------------------------
|
||||
module unfolded_pattern() {
|
||||
GrooveDepth = TotalThickness - BaseThickness;
|
||||
|
||||
// To prevent export errors, we perform the cuts sequentially.
|
||||
// This is more stable than a single, complex difference().
|
||||
difference() {
|
||||
// Start with the result of the first cut...
|
||||
difference() {
|
||||
// 1. Create the base plate
|
||||
cube([TotalWidth, TotalLength, TotalThickness], center = true);
|
||||
|
||||
// 2. Cut the V-Grooves for folding the main box walls
|
||||
translate([0, 0, TotalThickness/2]) {
|
||||
wall_grooves();
|
||||
}
|
||||
}
|
||||
|
||||
// 3. ...and then cut the internal rectangular slots from that result.
|
||||
if (Nb_Boxes_U > 1 || Nb_Boxes_V > 1) {
|
||||
translate([0,0,TotalThickness/2 - GrooveDepth/2])
|
||||
internal_grooves();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Helper modules
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
// Module for creating the grooves for the outer walls
|
||||
// Reverted to simple rectangular slots as a final workaround to bypass
|
||||
// a persistent, unfixable geometry kernel bug with V-grooves.
|
||||
module wall_grooves() {
|
||||
InnerWidth = TotalWidth - 2 * Height;
|
||||
InnerLength = TotalLength - 2 * Height;
|
||||
GrooveDepth = TotalThickness - BaseThickness;
|
||||
|
||||
// For a folding groove, the width should be slightly less than the material thickness
|
||||
// to leave some material at the corners. We'll use the depth as a proxy.
|
||||
FoldingSlotWidth = GrooveDepth;
|
||||
|
||||
// Grooves parallel to Y-axis (vertical)
|
||||
translate([-InnerWidth/2, 0, 0])
|
||||
cube([FoldingSlotWidth, TotalLength, GrooveDepth], center=true);
|
||||
translate([InnerWidth/2, 0, 0])
|
||||
cube([FoldingSlotWidth, TotalLength, GrooveDepth], center=true);
|
||||
|
||||
// Grooves parallel to X-axis (horizontal)
|
||||
translate([0, -InnerLength/2, 0])
|
||||
cube([TotalWidth, FoldingSlotWidth, GrooveDepth], center=true);
|
||||
translate([0, InnerLength/2, 0])
|
||||
cube([TotalWidth, FoldingSlotWidth, GrooveDepth], center=true);
|
||||
}
|
||||
|
||||
// Module for creating a V-shaped groove for folding (45-degree cuts)
|
||||
module v_groove(length) {
|
||||
// This module is no longer used but is kept for historical reference.
|
||||
}
|
||||
|
||||
// Module for creating the grooves for the internal compartments
|
||||
module internal_grooves() {
|
||||
InnerWidth = TotalWidth - 2 * Height;
|
||||
InnerLength = TotalLength - 2 * Height;
|
||||
GrooveDepth = TotalThickness - BaseThickness;
|
||||
|
||||
CompartmentWidth = (InnerWidth - (Nb_Boxes_U - 1) * Slot_Width_Walls) / Nb_Boxes_U;
|
||||
CompartmentLength = (InnerLength - (Nb_Boxes_V - 1) * Slot_Width_Walls) / Nb_Boxes_V;
|
||||
|
||||
// Internal vertical grooves
|
||||
if (Nb_Boxes_U > 1) {
|
||||
for (i = [1 : Nb_Boxes_U - 1]) {
|
||||
x_pos = -InnerWidth/2 + i * CompartmentWidth + (i - 1/2) * Slot_Width_Walls;
|
||||
translate([x_pos, 0, 0])
|
||||
cube([Slot_Width_Walls, InnerLength, GrooveDepth], center = true);
|
||||
}
|
||||
}
|
||||
|
||||
// Internal horizontal grooves
|
||||
if (Nb_Boxes_V > 1) {
|
||||
for (i = [1 : Nb_Boxes_V - 1]) {
|
||||
y_pos = -InnerLength/2 + i * CompartmentLength + (i - 1/2) * Slot_Width_Walls;
|
||||
translate([0, y_pos, 0])
|
||||
cube([InnerWidth, Slot_Width_Walls, GrooveDepth], center = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Modules for Folded View
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
// Generates the fully assembled 3D box
|
||||
module folded_box() {
|
||||
// Inner dimensions of the box
|
||||
InnerWidth = TotalWidth - 2 * Height;
|
||||
InnerLength = TotalLength - 2 * Height;
|
||||
|
||||
// Material thickness for all parts
|
||||
wall_thickness = TotalThickness;
|
||||
|
||||
// 1. Base Plate
|
||||
translate([0, 0, wall_thickness / 2])
|
||||
cube([InnerWidth, InnerLength, wall_thickness], center = true);
|
||||
|
||||
// 2. Outer Walls
|
||||
// South Wall (bottom) - Full Width
|
||||
translate([0, -InnerLength/2, Height/2 + wall_thickness])
|
||||
rotate([90, 0, 0])
|
||||
cube([InnerWidth, Height, wall_thickness], center=true);
|
||||
|
||||
// North Wall (top) - Full Width
|
||||
translate([0, InnerLength/2, Height/2 + wall_thickness])
|
||||
rotate([-90, 0, 0])
|
||||
cube([InnerWidth, Height, wall_thickness], center=true);
|
||||
|
||||
// West Wall (left) - Shortened to fit between North/South walls
|
||||
translate([-InnerWidth/2, 0, Height/2 + wall_thickness])
|
||||
rotate([0, 90, 0])
|
||||
cube([Height, InnerLength - 2 * wall_thickness, wall_thickness], center=true);
|
||||
|
||||
// East Wall (right) - Shortened to fit between North/South walls
|
||||
translate([InnerWidth/2, 0, Height/2 + wall_thickness])
|
||||
rotate([0, -90, 0])
|
||||
cube([Height, InnerLength - 2 * wall_thickness, wall_thickness], center=true);
|
||||
|
||||
// 3. Internal Dividers
|
||||
internal_dividers_folded();
|
||||
}
|
||||
|
||||
// Generates the interlocking internal dividers for the folded view
|
||||
module internal_dividers_folded() {
|
||||
InnerWidth = TotalWidth - 2 * Height;
|
||||
InnerLength = TotalLength - 2 * Height;
|
||||
divider_thickness = Slot_Width_Walls; // Use slot width as the divider material thickness
|
||||
|
||||
// Calculate compartment sizes
|
||||
Compartment_U = (InnerWidth + divider_thickness) / Nb_Boxes_U;
|
||||
Compartment_V = (InnerLength + divider_thickness) / Nb_Boxes_V;
|
||||
|
||||
// Vertical dividers (U-direction)
|
||||
for (i = [1 : Nb_Boxes_U - 1]) {
|
||||
x_pos = -InnerWidth/2 + i * Compartment_U - divider_thickness/2;
|
||||
difference() {
|
||||
// Main divider piece
|
||||
translate([x_pos, 0, Height/2 + TotalThickness])
|
||||
cube([divider_thickness, InnerLength, Height], center=true);
|
||||
// Slots for horizontal dividers (top-down)
|
||||
for (j = [1 : Nb_Boxes_V - 1]) {
|
||||
y_pos = -InnerLength/2 + j * Compartment_V - divider_thickness/2;
|
||||
translate([x_pos, y_pos, Height * 0.75 + TotalThickness])
|
||||
cube([divider_thickness + 0.1, divider_thickness, Height/2], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Horizontal dividers (V-direction)
|
||||
for (j = [1 : Nb_Boxes_V - 1]) {
|
||||
y_pos = -InnerLength/2 + j * Compartment_V - divider_thickness/2;
|
||||
difference() {
|
||||
// Main divider piece
|
||||
translate([0, y_pos, Height/2 + TotalThickness])
|
||||
cube([InnerWidth, divider_thickness, Height], center=true);
|
||||
// Slots for vertical dividers (bottom-up)
|
||||
for (i = [1 : Nb_Boxes_U - 1]) {
|
||||
x_pos = -InnerWidth/2 + i * Compartment_U - divider_thickness/2;
|
||||
translate([x_pos, y_pos, Height * 0.25 + TotalThickness])
|
||||
cube([divider_thickness, divider_thickness + 0.1, Height/2], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Module for exporting all parts separately
|
||||
// ---------------------------------------------------------------------
|
||||
module export_layout() {
|
||||
wall_thickness = TotalThickness;
|
||||
InnerWidth = TotalWidth - 2 * Height;
|
||||
InnerLength = TotalLength - 2 * Height;
|
||||
|
||||
// 1. Base Plate
|
||||
translate([0, 0, -TotalThickness/2])
|
||||
cube([InnerWidth, InnerLength, wall_thickness], center = true);
|
||||
|
||||
// Spacing for laying out parts
|
||||
spacing = TotalWidth;
|
||||
|
||||
// 2. Outer Walls
|
||||
translate([spacing, 0, 0])
|
||||
cube([InnerWidth, Height, wall_thickness], center=true); // South
|
||||
translate([spacing, Height + 10, 0])
|
||||
cube([InnerWidth, Height, wall_thickness], center=true); // North
|
||||
|
||||
translate([spacing + InnerWidth + 10, 0, 0])
|
||||
cube([InnerLength - 2 * wall_thickness, Height, wall_thickness], center=true); // West
|
||||
translate([spacing + InnerWidth + 10, Height + 10, 0])
|
||||
cube([InnerLength - 2 * wall_thickness, Height, wall_thickness], center=true); // East
|
||||
|
||||
// 3. Internal Dividers
|
||||
divider_thickness = Slot_Width_Walls;
|
||||
Compartment_U = (InnerWidth + divider_thickness) / Nb_Boxes_U;
|
||||
Compartment_V = (InnerLength + divider_thickness) / Nb_Boxes_V;
|
||||
|
||||
// Place all vertical dividers in a row
|
||||
for (i = [1 : Nb_Boxes_U - 1]) {
|
||||
translate([2 * spacing + (i-1)*(divider_thickness+10), 0, 0])
|
||||
internal_divider_vertical_export(InnerLength, Compartment_V);
|
||||
}
|
||||
|
||||
// Place all horizontal dividers in a row
|
||||
for (j = [1 : Nb_Boxes_V - 1]) {
|
||||
translate([2 * spacing, (j-1)*(Height+10) + Height + 10, 0])
|
||||
internal_divider_horizontal_export(InnerWidth, Compartment_U);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper modules for export layout (without difference operations)
|
||||
module internal_divider_vertical_export(length, compartment_v_size) {
|
||||
divider_thickness = Slot_Width_Walls;
|
||||
difference() {
|
||||
cube([divider_thickness, length, Height], center=true);
|
||||
// Notches for horizontal dividers (bottom-up)
|
||||
for (i = [1 : Nb_Boxes_V - 1]) {
|
||||
y_pos = -length/2 + i * compartment_v_size - divider_thickness/2;
|
||||
translate([0, y_pos, -Height/4])
|
||||
cube([divider_thickness + 0.1, divider_thickness, Height/2], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module internal_divider_horizontal_export(length, compartment_u_size) {
|
||||
divider_thickness = Slot_Width_Walls;
|
||||
difference() {
|
||||
cube([length, divider_thickness, Height], center=true);
|
||||
// Notches for vertical dividers (top-down)
|
||||
for (j = [1 : Nb_Boxes_U - 1]) {
|
||||
x_pos = -length/2 + j * compartment_u_size - divider_thickness/2;
|
||||
translate([x_pos, 0, Height/4])
|
||||
cube([divider_thickness, divider_thickness + 0.1, Height/2], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Module to generate a markdown cut plan for the operator.
|
||||
// This version avoids all list manipulation for maximum compatibility.
|
||||
// ---------------------------------------------------------------------
|
||||
module generate_cut_plan_text() {
|
||||
// --- Calculations ---
|
||||
InnerWidth = TotalWidth - 2 * Height;
|
||||
InnerLength = TotalLength - 2 * Height;
|
||||
GrooveDepth = TotalThickness - BaseThickness;
|
||||
|
||||
// --- Markdown Output ---
|
||||
echo("# Saw Operator Cut Plan");
|
||||
echo(str("## Board Dimensions: `", TotalWidth, " x ", TotalLength, " mm`"));
|
||||
echo("");
|
||||
echo("## Specifications");
|
||||
echo(str("* **V-Groove Spec:** Depth `", GrooveDepth, " mm`"));
|
||||
echo(str("* **Slot Spec:** Width `", Slot_Width_Walls, " mm`, Depth `", GrooveDepth, " mm`"));
|
||||
echo("");
|
||||
echo("## Blade Setup");
|
||||
echo("* **For V-Grooves:** Set saw blade angle to **45 degrees**.");
|
||||
echo("* **For Slots:** Set saw blade angle to **0 degrees** (straight up).");
|
||||
echo("");
|
||||
|
||||
// --- Setup 1: Vertical Cuts ---
|
||||
echo("## SETUP 1: VERTICAL CUTS");
|
||||
echo("All distances are from the LEFT edge. Flip board for cuts > 50%.");
|
||||
echo("");
|
||||
echo(str("* `", Height, " mm` -- **V-GROOVE**"));
|
||||
if (Nb_Boxes_U > 1) {
|
||||
for (i = [1 : Nb_Boxes_U - 1]) {
|
||||
pos = Height + i * ((InnerWidth - (Nb_Boxes_U - 1) * Slot_Width_Walls) / Nb_Boxes_U) + i * Slot_Width_Walls;
|
||||
echo(str("* `", pos, " mm` -- **SLOT**"));
|
||||
}
|
||||
}
|
||||
echo(str("* `", TotalWidth - Height, " mm` -- **V-GROOVE**"));
|
||||
echo("");
|
||||
|
||||
// --- Setup 2: Horizontal Cuts ---
|
||||
echo("## SETUP 2: HORIZONTAL CUTS");
|
||||
echo("Rotate board 90 deg. All distances from the NEW LEFT edge.");
|
||||
echo("");
|
||||
echo(str("* `", Height, " mm` -- **V-GROOVE**"));
|
||||
if (Nb_Boxes_V > 1) {
|
||||
for (i = [1 : Nb_Boxes_V - 1]) {
|
||||
pos = Height + i * ((InnerLength - (Nb_Boxes_V - 1) * Slot_Width_Walls) / Nb_Boxes_V) + i * Slot_Width_Walls;
|
||||
echo(str("* `", pos, " mm` -- **SLOT**"));
|
||||
}
|
||||
}
|
||||
echo(str("* `", TotalLength - Height, " mm` -- **V-GROOVE**"));
|
||||
|
||||
echo("");
|
||||
echo("---");
|
||||
echo("*End of Plan*");
|
||||
|
||||
// Generate a tiny invisible cube because OpenSCAD needs to produce some geometry.
|
||||
cube(0.01);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Render the final object
|
||||
// ---------------------------------------------------------------------
|
||||
if (view_mode == "export") {
|
||||
export_layout();
|
||||
} else if (view_mode == "dxf") {
|
||||
// Project the 2D unfolded pattern for DXF export
|
||||
projection(cut = true) unfolded_pattern();
|
||||
} else if (view_mode == "cutplan") {
|
||||
generate_cut_plan_text();
|
||||
} else {
|
||||
if (Folded_View) {
|
||||
folded_box();
|
||||
} else {
|
||||
unfolded_pattern();
|
||||
}
|
||||
}
|
||||
BIN
products/poly-mech/cad/drawers/tools/box_folding_tool.step
(Stored with Git LFS)
BIN
products/poly-mech/cad/drawers/tools/box_folding_tool.step
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/drawers/tools/box_folding_tool_false.png
(Stored with Git LFS)
BIN
products/poly-mech/cad/drawers/tools/box_folding_tool_false.png
(Stored with Git LFS)
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -1,982 +0,0 @@
|
||||
solid OpenSCAD_Model
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -4 -167.5 5
|
||||
vertex -4 -4 45
|
||||
vertex -4 -4 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -4 -167.5 85
|
||||
vertex -4 -4 45
|
||||
vertex -4 -167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -4 -4 45
|
||||
vertex -4 -167.5 85
|
||||
vertex -4 -4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -4 4 45
|
||||
vertex -4 167.5 5
|
||||
vertex -4 4 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -4 167.5 5
|
||||
vertex -4 4 45
|
||||
vertex -4 167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 -0 0
|
||||
outer loop
|
||||
vertex -4 167.5 85
|
||||
vertex -4 4 45
|
||||
vertex -4 4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -0 0 1
|
||||
outer loop
|
||||
vertex -172.5 165 85
|
||||
vertex -167.5 4 85
|
||||
vertex -167.5 165 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -167.5 4 85
|
||||
vertex -172.5 165 85
|
||||
vertex -167.5 -4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -172.5 -165 85
|
||||
vertex -167.5 -4 85
|
||||
vertex -172.5 165 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -167.5 -4 85
|
||||
vertex -172.5 -165 85
|
||||
vertex -167.5 -165 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -0 0 1
|
||||
outer loop
|
||||
vertex -167.5 4 85
|
||||
vertex -4 -4 85
|
||||
vertex -4 4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -4 -4 85
|
||||
vertex -167.5 4 85
|
||||
vertex -167.5 -4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex 170 172.5 85
|
||||
vertex 4 167.5 85
|
||||
vertex 170 167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -4 4 85
|
||||
vertex 4 4 85
|
||||
vertex 4 167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex 4 4 85
|
||||
vertex -4 4 85
|
||||
vertex 4 -4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -4 4 85
|
||||
vertex 4 167.5 85
|
||||
vertex -4 167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex 170 172.5 85
|
||||
vertex -4 167.5 85
|
||||
vertex 4 167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -0 0 1
|
||||
outer loop
|
||||
vertex -170 172.5 85
|
||||
vertex -4 167.5 85
|
||||
vertex 170 172.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -4 167.5 85
|
||||
vertex -170 172.5 85
|
||||
vertex -170 167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -0 0 1
|
||||
outer loop
|
||||
vertex 4 4 85
|
||||
vertex 167.5 -4 85
|
||||
vertex 167.5 4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex 167.5 -4 85
|
||||
vertex 4 4 85
|
||||
vertex 4 -4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex 167.5 4 85
|
||||
vertex 172.5 165 85
|
||||
vertex 167.5 165 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex 172.5 165 85
|
||||
vertex 167.5 4 85
|
||||
vertex 172.5 -165 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -0 0 1
|
||||
outer loop
|
||||
vertex 167.5 -4 85
|
||||
vertex 172.5 -165 85
|
||||
vertex 167.5 4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex 172.5 -165 85
|
||||
vertex 167.5 -4 85
|
||||
vertex 167.5 -165 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -0 0 1
|
||||
outer loop
|
||||
vertex 4 -167.5 85
|
||||
vertex 170 -172.5 85
|
||||
vertex 170 -167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -4 -4 85
|
||||
vertex 4 -4 85
|
||||
vertex -4 4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex 4 -4 85
|
||||
vertex -4 -4 85
|
||||
vertex 4 -167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -4 -167.5 85
|
||||
vertex 4 -167.5 85
|
||||
vertex -4 -4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -0 0 1
|
||||
outer loop
|
||||
vertex -4 -167.5 85
|
||||
vertex 170 -172.5 85
|
||||
vertex 4 -167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -170 -172.5 85
|
||||
vertex -4 -167.5 85
|
||||
vertex -170 -167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -4 -167.5 85
|
||||
vertex -170 -172.5 85
|
||||
vertex 170 -172.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 -0 0
|
||||
outer loop
|
||||
vertex 4 -167.5 85
|
||||
vertex 4 -4 45
|
||||
vertex 4 -4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex 4 -167.5 5
|
||||
vertex 4 -4 45
|
||||
vertex 4 -167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex 4 -4 45
|
||||
vertex 4 -167.5 5
|
||||
vertex 4 -4 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex 4 4 45
|
||||
vertex 4 167.5 85
|
||||
vertex 4 4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex 4 167.5 85
|
||||
vertex 4 4 45
|
||||
vertex 4 167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex 4 167.5 5
|
||||
vertex 4 4 45
|
||||
vertex 4 4 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 -1
|
||||
outer loop
|
||||
vertex 170 -165 5
|
||||
vertex 172.5 165 5
|
||||
vertex 172.5 -165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -0 0 -1
|
||||
outer loop
|
||||
vertex 172.5 165 5
|
||||
vertex 170 -165 5
|
||||
vertex 170 165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex 167.5 -4 5
|
||||
vertex 4 -4 5
|
||||
vertex 167.5 -165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -0 0 1
|
||||
outer loop
|
||||
vertex 167.5 -165 5
|
||||
vertex 170 -167.5 5
|
||||
vertex 170 -165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex 4 -167.5 5
|
||||
vertex 167.5 -165 5
|
||||
vertex 4 -4 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex 167.5 -165 5
|
||||
vertex 4 -167.5 5
|
||||
vertex 170 -167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex 170 167.5 5
|
||||
vertex 167.5 165 5
|
||||
vertex 170 165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -0 0 1
|
||||
outer loop
|
||||
vertex 4 167.5 5
|
||||
vertex 167.5 165 5
|
||||
vertex 170 167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex 4 4 5
|
||||
vertex 167.5 165 5
|
||||
vertex 4 167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex 167.5 165 5
|
||||
vertex 4 4 5
|
||||
vertex 167.5 4 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 -1
|
||||
outer loop
|
||||
vertex -170 -172.5 5
|
||||
vertex 170 -170 5
|
||||
vertex 170 -172.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -0 0 -1
|
||||
outer loop
|
||||
vertex 170 -170 5
|
||||
vertex -170 -172.5 5
|
||||
vertex -170 -170 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 -1
|
||||
outer loop
|
||||
vertex -170 170 5
|
||||
vertex 170 172.5 5
|
||||
vertex 170 170 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -0 0 -1
|
||||
outer loop
|
||||
vertex 170 172.5 5
|
||||
vertex -170 170 5
|
||||
vertex -170 172.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -4 167.5 5
|
||||
vertex -167.5 165 5
|
||||
vertex -4 4 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -0 0 1
|
||||
outer loop
|
||||
vertex -170 167.5 5
|
||||
vertex -167.5 165 5
|
||||
vertex -4 167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -167.5 165 5
|
||||
vertex -170 167.5 5
|
||||
vertex -170 165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -4 4 5
|
||||
vertex -167.5 165 5
|
||||
vertex -167.5 4 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -167.5 -165 5
|
||||
vertex -4 -4 5
|
||||
vertex -167.5 -4 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -4 -4 5
|
||||
vertex -167.5 -165 5
|
||||
vertex -4 -167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -170 -167.5 5
|
||||
vertex -167.5 -165 5
|
||||
vertex -170 -165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 1
|
||||
outer loop
|
||||
vertex -167.5 -165 5
|
||||
vertex -170 -167.5 5
|
||||
vertex -4 -167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 -1
|
||||
outer loop
|
||||
vertex -172.5 -165 5
|
||||
vertex -170 165 5
|
||||
vertex -170 -165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -0 0 -1
|
||||
outer loop
|
||||
vertex -170 165 5
|
||||
vertex -172.5 -165 5
|
||||
vertex -172.5 165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 0
|
||||
outer loop
|
||||
vertex -167.5 -4 85
|
||||
vertex -4 -4 45
|
||||
vertex -4 -4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 0
|
||||
outer loop
|
||||
vertex -167.5 -4 5
|
||||
vertex -4 -4 45
|
||||
vertex -167.5 -4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 -0
|
||||
outer loop
|
||||
vertex -4 -4 45
|
||||
vertex -167.5 -4 5
|
||||
vertex -4 -4 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 0
|
||||
outer loop
|
||||
vertex 4 -4 45
|
||||
vertex 167.5 -4 85
|
||||
vertex 4 -4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 0
|
||||
outer loop
|
||||
vertex 167.5 -4 5
|
||||
vertex 4 -4 45
|
||||
vertex 4 -4 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 0
|
||||
outer loop
|
||||
vertex 4 -4 45
|
||||
vertex 167.5 -4 5
|
||||
vertex 167.5 -4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 -0
|
||||
outer loop
|
||||
vertex -4 4 45
|
||||
vertex -167.5 4 85
|
||||
vertex -4 4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 0
|
||||
outer loop
|
||||
vertex -167.5 4 5
|
||||
vertex -4 4 45
|
||||
vertex -4 4 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 0
|
||||
outer loop
|
||||
vertex -4 4 45
|
||||
vertex -167.5 4 5
|
||||
vertex -167.5 4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 0
|
||||
outer loop
|
||||
vertex 167.5 4 85
|
||||
vertex 4 4 45
|
||||
vertex 4 4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 -0
|
||||
outer loop
|
||||
vertex 167.5 4 5
|
||||
vertex 4 4 45
|
||||
vertex 167.5 4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 0
|
||||
outer loop
|
||||
vertex 4 4 45
|
||||
vertex 167.5 4 5
|
||||
vertex 4 4 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -170 170 0
|
||||
vertex -170 167.5 5
|
||||
vertex -170 170 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -170 170 0
|
||||
vertex -170 165 5
|
||||
vertex -170 167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -170 170 0
|
||||
vertex -170 -165 5
|
||||
vertex -170 165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -170 -170 0
|
||||
vertex -170 -165 5
|
||||
vertex -170 170 0
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 -0 0
|
||||
outer loop
|
||||
vertex -170 -165 5
|
||||
vertex -170 -170 0
|
||||
vertex -170 -167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -170 -170 5
|
||||
vertex -170 -167.5 5
|
||||
vertex -170 -170 0
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -170 -167.5 5
|
||||
vertex -170 -170 5
|
||||
vertex -170 -167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -170 -172.5 85
|
||||
vertex -170 -170 5
|
||||
vertex -170 -172.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -170 -170 5
|
||||
vertex -170 -172.5 85
|
||||
vertex -170 -167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -170 170 5
|
||||
vertex -170 172.5 85
|
||||
vertex -170 172.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -170 167.5 85
|
||||
vertex -170 170 5
|
||||
vertex -170 167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -170 170 5
|
||||
vertex -170 167.5 85
|
||||
vertex -170 172.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex 170 -167.5 85
|
||||
vertex 170 -170 5
|
||||
vertex 170 -167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 -0 0
|
||||
outer loop
|
||||
vertex 170 -172.5 85
|
||||
vertex 170 -170 5
|
||||
vertex 170 -167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex 170 -170 5
|
||||
vertex 170 -172.5 85
|
||||
vertex 170 -172.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex 170 172.5 85
|
||||
vertex 170 170 5
|
||||
vertex 170 172.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 -0 0
|
||||
outer loop
|
||||
vertex 170 167.5 85
|
||||
vertex 170 170 5
|
||||
vertex 170 172.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex 170 167.5 5
|
||||
vertex 170 170 5
|
||||
vertex 170 167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex 170 170 5
|
||||
vertex 170 167.5 5
|
||||
vertex 170 170 0
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 -0 0
|
||||
outer loop
|
||||
vertex 170 165 5
|
||||
vertex 170 170 0
|
||||
vertex 170 167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 -0 0
|
||||
outer loop
|
||||
vertex 170 -165 5
|
||||
vertex 170 170 0
|
||||
vertex 170 165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex 170 -170 0
|
||||
vertex 170 -165 5
|
||||
vertex 170 -167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex 170 -170 0
|
||||
vertex 170 -167.5 5
|
||||
vertex 170 -170 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex 170 -165 5
|
||||
vertex 170 -170 0
|
||||
vertex 170 170 0
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 -0
|
||||
outer loop
|
||||
vertex 170 170 0
|
||||
vertex -170 170 5
|
||||
vertex 170 170 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 0
|
||||
outer loop
|
||||
vertex -170 170 5
|
||||
vertex 170 170 0
|
||||
vertex -170 170 0
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 0 -1
|
||||
outer loop
|
||||
vertex -170 -170 0
|
||||
vertex 170 170 0
|
||||
vertex 170 -170 0
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -0 0 -1
|
||||
outer loop
|
||||
vertex 170 170 0
|
||||
vertex -170 -170 0
|
||||
vertex -170 170 0
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 0
|
||||
outer loop
|
||||
vertex -170 -170 0
|
||||
vertex 170 -170 5
|
||||
vertex -170 -170 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 -0
|
||||
outer loop
|
||||
vertex 170 -170 5
|
||||
vertex -170 -170 0
|
||||
vertex 170 -170 0
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 0
|
||||
outer loop
|
||||
vertex -170 -172.5 5
|
||||
vertex 170 -172.5 85
|
||||
vertex -170 -172.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 -0
|
||||
outer loop
|
||||
vertex 170 -172.5 85
|
||||
vertex -170 -172.5 5
|
||||
vertex 170 -172.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 -0
|
||||
outer loop
|
||||
vertex -4 -167.5 5
|
||||
vertex -170 -167.5 85
|
||||
vertex -4 -167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 0
|
||||
outer loop
|
||||
vertex -170 -167.5 85
|
||||
vertex -4 -167.5 5
|
||||
vertex -170 -167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 -0
|
||||
outer loop
|
||||
vertex 170 -167.5 5
|
||||
vertex 4 -167.5 85
|
||||
vertex 170 -167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 0
|
||||
outer loop
|
||||
vertex 4 -167.5 85
|
||||
vertex 170 -167.5 5
|
||||
vertex 4 -167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 -0
|
||||
outer loop
|
||||
vertex 170 172.5 5
|
||||
vertex -170 172.5 85
|
||||
vertex 170 172.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 0
|
||||
outer loop
|
||||
vertex -170 172.5 85
|
||||
vertex 170 172.5 5
|
||||
vertex -170 172.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 0
|
||||
outer loop
|
||||
vertex -170 167.5 5
|
||||
vertex -4 167.5 85
|
||||
vertex -170 167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 -0
|
||||
outer loop
|
||||
vertex -4 167.5 85
|
||||
vertex -170 167.5 5
|
||||
vertex -4 167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 0
|
||||
outer loop
|
||||
vertex 4 167.5 5
|
||||
vertex 170 167.5 85
|
||||
vertex 4 167.5 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 -0
|
||||
outer loop
|
||||
vertex 170 167.5 85
|
||||
vertex 4 167.5 5
|
||||
vertex 170 167.5 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 -0 0
|
||||
outer loop
|
||||
vertex -167.5 -165 85
|
||||
vertex -167.5 -4 5
|
||||
vertex -167.5 -4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex -167.5 -4 5
|
||||
vertex -167.5 -165 85
|
||||
vertex -167.5 -165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 -0 0
|
||||
outer loop
|
||||
vertex -167.5 4 85
|
||||
vertex -167.5 165 5
|
||||
vertex -167.5 165 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex -167.5 165 5
|
||||
vertex -167.5 4 85
|
||||
vertex -167.5 4 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 0
|
||||
outer loop
|
||||
vertex -170 -165 5
|
||||
vertex -172.5 -165 85
|
||||
vertex -172.5 -165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 0
|
||||
outer loop
|
||||
vertex -172.5 -165 85
|
||||
vertex -170 -165 5
|
||||
vertex -167.5 -165 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 -0
|
||||
outer loop
|
||||
vertex -167.5 -165 85
|
||||
vertex -170 -165 5
|
||||
vertex -167.5 -165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex -172.5 -165 5
|
||||
vertex -172.5 165 85
|
||||
vertex -172.5 165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 -0 0
|
||||
outer loop
|
||||
vertex -172.5 165 85
|
||||
vertex -172.5 -165 5
|
||||
vertex -172.5 -165 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 0
|
||||
outer loop
|
||||
vertex -170 165 5
|
||||
vertex -167.5 165 85
|
||||
vertex -167.5 165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 0
|
||||
outer loop
|
||||
vertex -167.5 165 85
|
||||
vertex -170 165 5
|
||||
vertex -172.5 165 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 0
|
||||
outer loop
|
||||
vertex -172.5 165 85
|
||||
vertex -170 165 5
|
||||
vertex -172.5 165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex 167.5 -165 5
|
||||
vertex 167.5 -4 85
|
||||
vertex 167.5 -4 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 -0 0
|
||||
outer loop
|
||||
vertex 167.5 -4 85
|
||||
vertex 167.5 -165 5
|
||||
vertex 167.5 -165 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 0 0
|
||||
outer loop
|
||||
vertex 167.5 4 5
|
||||
vertex 167.5 165 85
|
||||
vertex 167.5 165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal -1 -0 0
|
||||
outer loop
|
||||
vertex 167.5 165 85
|
||||
vertex 167.5 4 5
|
||||
vertex 167.5 4 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 0
|
||||
outer loop
|
||||
vertex 170 165 5
|
||||
vertex 172.5 165 85
|
||||
vertex 172.5 165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 0
|
||||
outer loop
|
||||
vertex 172.5 165 85
|
||||
vertex 170 165 5
|
||||
vertex 167.5 165 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 1 0
|
||||
outer loop
|
||||
vertex 167.5 165 85
|
||||
vertex 170 165 5
|
||||
vertex 167.5 165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 -0 0
|
||||
outer loop
|
||||
vertex 172.5 -165 85
|
||||
vertex 172.5 165 5
|
||||
vertex 172.5 165 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 1 0 0
|
||||
outer loop
|
||||
vertex 172.5 165 5
|
||||
vertex 172.5 -165 85
|
||||
vertex 172.5 -165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 0
|
||||
outer loop
|
||||
vertex 170 -165 5
|
||||
vertex 167.5 -165 85
|
||||
vertex 167.5 -165 5
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 0
|
||||
outer loop
|
||||
vertex 167.5 -165 85
|
||||
vertex 170 -165 5
|
||||
vertex 172.5 -165 85
|
||||
endloop
|
||||
endfacet
|
||||
facet normal 0 -1 -0
|
||||
outer loop
|
||||
vertex 172.5 -165 85
|
||||
vertex 170 -165 5
|
||||
vertex 172.5 -165 5
|
||||
endloop
|
||||
endfacet
|
||||
endsolid OpenSCAD_Model
|
||||
@ -1,214 +0,0 @@
|
||||
0
|
||||
SECTION
|
||||
2
|
||||
BLOCKS
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
SECTION
|
||||
2
|
||||
ENTITIES
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-250
|
||||
20
|
||||
-250
|
||||
11
|
||||
250
|
||||
21
|
||||
-250
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
250
|
||||
20
|
||||
-250
|
||||
11
|
||||
250
|
||||
21
|
||||
250
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
250
|
||||
20
|
||||
250
|
||||
11
|
||||
-250
|
||||
21
|
||||
250
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-250
|
||||
20
|
||||
250
|
||||
11
|
||||
-250
|
||||
21
|
||||
-250
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-165
|
||||
20
|
||||
-4
|
||||
11
|
||||
-165
|
||||
21
|
||||
4
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-165
|
||||
20
|
||||
4
|
||||
11
|
||||
-4
|
||||
21
|
||||
4
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-4
|
||||
20
|
||||
4
|
||||
11
|
||||
-4
|
||||
21
|
||||
165
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-4
|
||||
20
|
||||
165
|
||||
11
|
||||
4
|
||||
21
|
||||
165
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
4
|
||||
20
|
||||
165
|
||||
11
|
||||
4
|
||||
21
|
||||
4
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
4
|
||||
20
|
||||
4
|
||||
11
|
||||
165
|
||||
21
|
||||
4
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
165
|
||||
20
|
||||
4
|
||||
11
|
||||
165
|
||||
21
|
||||
-4
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
165
|
||||
20
|
||||
-4
|
||||
11
|
||||
4
|
||||
21
|
||||
-4
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
4
|
||||
20
|
||||
-4
|
||||
11
|
||||
4
|
||||
21
|
||||
-165
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
4
|
||||
20
|
||||
-165
|
||||
11
|
||||
-4
|
||||
21
|
||||
-165
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-4
|
||||
20
|
||||
-165
|
||||
11
|
||||
-4
|
||||
21
|
||||
-4
|
||||
0
|
||||
LINE
|
||||
8
|
||||
0
|
||||
10
|
||||
-4
|
||||
20
|
||||
-4
|
||||
11
|
||||
-165
|
||||
21
|
||||
-4
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
SECTION
|
||||
2
|
||||
OBJECTS
|
||||
0
|
||||
DICTIONARY
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
EOF
|
||||
@ -1,101 +0,0 @@
|
||||
import argparse
|
||||
|
||||
def generate_cut_plan(total_width, total_length, height, base_thickness, total_thickness, slot_width, u_boxes, v_boxes):
|
||||
"""
|
||||
Calculates and prints a markdown cut plan for the operator.
|
||||
"""
|
||||
|
||||
# --- Calculations ---
|
||||
inner_width = total_width - 2 * height
|
||||
inner_length = total_length - 2 * height
|
||||
groove_depth = total_thickness - base_thickness
|
||||
|
||||
# --- Collect all cut positions ---
|
||||
vertical_cuts = []
|
||||
if u_boxes > 1:
|
||||
compartment_width = (inner_width - (u_boxes - 1) * slot_width) / u_boxes
|
||||
for i in range(1, u_boxes):
|
||||
pos = height + (i * compartment_width) + (i * slot_width)
|
||||
vertical_cuts.append(pos)
|
||||
vertical_cuts.extend([height, total_width - height])
|
||||
|
||||
horizontal_cuts = []
|
||||
if v_boxes > 1:
|
||||
compartment_length = (inner_length - (v_boxes - 1) * slot_width) / v_boxes
|
||||
for i in range(1, v_boxes):
|
||||
pos = height + (i * compartment_length) + (i * slot_width)
|
||||
horizontal_cuts.append(pos)
|
||||
horizontal_cuts.extend([height, total_length - height])
|
||||
|
||||
# --- Markdown Output ---
|
||||
print("# Saw Operator Cut Plan")
|
||||
print(f"## Board Dimensions: `{total_width} x {total_length} mm`")
|
||||
print("")
|
||||
print("## Specifications")
|
||||
print(f"* **V-Groove Spec:** Depth `{groove_depth:.2f} mm`")
|
||||
print(f"* **Slot Spec:** Width `{slot_width} mm`, Depth `{groove_depth:.2f} mm`")
|
||||
print("")
|
||||
print("## Blade Setup")
|
||||
print("* **For V-Grooves:** Set saw blade angle to **45 degrees**.")
|
||||
print("* **For Slots:** Set saw blade angle to **0 degrees** (straight up).")
|
||||
print("")
|
||||
|
||||
# --- Setup 1: Vertical Cuts ---
|
||||
print("## SETUP 1: VERTICAL CUTS")
|
||||
print("### 1. Reference from LEFT edge:")
|
||||
left_cuts = sorted([dist for dist in vertical_cuts if dist <= total_width / 2])
|
||||
for dist in left_cuts:
|
||||
cut_type = "V-GROOVE" if dist == height else "SLOT"
|
||||
print(f"* Set fence to: `{dist:.2f} mm` -- for **{cut_type}**")
|
||||
|
||||
print("### 2. Reference from RIGHT edge (FLIP board 180 deg):")
|
||||
right_cuts = sorted([total_width - dist for dist in vertical_cuts if dist > total_width / 2])
|
||||
for dist in right_cuts:
|
||||
abs_pos = total_width - dist
|
||||
cut_type = "V-GROOVE" if abs_pos == (total_width - height) else "SLOT"
|
||||
print(f"* Set fence to: `{dist:.2f} mm` -- for **{cut_type}**")
|
||||
print("")
|
||||
|
||||
# --- Setup 2: Horizontal Cuts ---
|
||||
print("## SETUP 2: HORIZONTAL CUTS")
|
||||
print("### 1. Rotate board 90 degrees CCW, reference from NEW LEFT edge (original BOTTOM edge):")
|
||||
bottom_cuts = sorted([dist for dist in horizontal_cuts if dist <= total_length / 2])
|
||||
for dist in bottom_cuts:
|
||||
cut_type = "V-GROOVE" if dist == height else "SLOT"
|
||||
print(f"* Set fence to: `{dist:.2f} mm` -- for **{cut_type}**")
|
||||
|
||||
print("### 2. Reference from NEW RIGHT edge (original TOP edge, FLIP board 180 deg):")
|
||||
top_cuts = sorted([total_length - dist for dist in horizontal_cuts if dist > total_length / 2])
|
||||
for dist in top_cuts:
|
||||
abs_pos = total_length - dist
|
||||
cut_type = "V-GROOVE" if abs_pos == (total_length - height) else "SLOT"
|
||||
print(f"* Set fence to: `{dist:.2f} mm` -- for **{cut_type}**")
|
||||
|
||||
print("")
|
||||
print("---")
|
||||
print("*End of Plan*")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Generate a cut plan for the poly-mech box.")
|
||||
parser.add_argument('--total-width', type=float, default=500, help='Total width of the board')
|
||||
parser.add_argument('--total-length', type=float, default=500, help='Total length of the board')
|
||||
parser.add_argument('--height', type=float, default=80, help='Height of the box walls')
|
||||
parser.add_argument('--base-thickness', type=float, default=3, help='Remaining thickness after V-groove')
|
||||
parser.add_argument('--total-thickness', type=float, default=8, help='Total thickness of the material')
|
||||
parser.add_argument('--slot-width', type=float, default=8, help='Width of the slots for internal dividers')
|
||||
parser.add_argument('--u-boxes', type=int, default=2, help='Number of boxes along the width (U-axis)')
|
||||
parser.add_argument('--v-boxes', type=int, default=2, help='Number of boxes along the length (V-axis)')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
generate_cut_plan(
|
||||
args.total_width,
|
||||
args.total_length,
|
||||
args.height,
|
||||
args.base_thickness,
|
||||
args.total_thickness,
|
||||
args.slot_width,
|
||||
args.u_boxes,
|
||||
args.v_boxes
|
||||
)
|
||||
@ -1,82 +0,0 @@
|
||||
# converter.py
|
||||
# A Python script for use with FreeCAD's command-line interface.
|
||||
# Converts a mesh file (like STL) into a solid model and exports it to STEP.
|
||||
|
||||
import sys
|
||||
import FreeCAD
|
||||
import Part
|
||||
import Mesh
|
||||
|
||||
# --- Argument Validation ---
|
||||
# The script name is sys.argv[0], followed by FreeCAD's internal args.
|
||||
# The actual script arguments start after that. We expect two: input and output files.
|
||||
# FreeCAD adds its own arguments, so we find our files at the end of the list.
|
||||
if len(sys.argv) < 3:
|
||||
print("Converter script usage: <input_file> <output_file>")
|
||||
sys.exit(1)
|
||||
|
||||
input_file_path = sys.argv[-2]
|
||||
output_file_path = sys.argv[-1]
|
||||
|
||||
print(f"Input file: {input_file_path}")
|
||||
print(f"Output file: {output_file_path}")
|
||||
|
||||
# --- Conversion Logic ---
|
||||
try:
|
||||
# 1. Load the mesh from the input STL file
|
||||
mesh = Mesh.read(input_file_path)
|
||||
|
||||
# 2. Split the mesh into its separate, unconnected components (shells)
|
||||
components = mesh.getSeparateComponents()
|
||||
print(f"Found {len(components)} separate components in the mesh.")
|
||||
|
||||
# 3. Convert each component mesh into a solid shape
|
||||
solids = []
|
||||
for i, component_mesh in enumerate(components):
|
||||
try:
|
||||
# Create a shape from the mesh component
|
||||
shape = Part.Shape()
|
||||
shape.makeShapeFromMesh(component_mesh.Topology, 0.1)
|
||||
|
||||
# Use a more robust method to ensure the shape is a solid
|
||||
# This can fix minor issues and is more reliable than direct conversion.
|
||||
if not shape.isNull() and shape.Faces:
|
||||
solid = Part.Solid(Part.Shell(shape.Faces))
|
||||
if solid.Volume > 0:
|
||||
solids.append(solid)
|
||||
else:
|
||||
# If creating a solid fails, try refining it first.
|
||||
refined_shape = shape.removeSplitter()
|
||||
if not refined_shape.isNull() and refined_shape.Faces:
|
||||
solid = Part.Solid(Part.Shell(refined_shape.Faces))
|
||||
if solid.Volume > 0:
|
||||
solids.append(solid)
|
||||
else:
|
||||
print(f"Warning: Component {i+1} could not be converted to a solid after refining.")
|
||||
else:
|
||||
print(f"Warning: Component {i+1} became null after refining.")
|
||||
else:
|
||||
print(f"Warning: Component {i+1} could not be converted to a shape.")
|
||||
|
||||
except Exception as ex:
|
||||
print(f"Warning: An exception occurred while processing component {i+1}: {ex}")
|
||||
|
||||
if not solids:
|
||||
print("Error: No valid solids could be created from the mesh.")
|
||||
sys.exit(1)
|
||||
|
||||
# 4. Combine all solids into a single compound part for export
|
||||
if len(solids) > 1:
|
||||
result_shape = Part.Compound(solids)
|
||||
else:
|
||||
result_shape = solids[0]
|
||||
|
||||
# 5. Export the final shape to a STEP file
|
||||
result_shape.exportStep(output_file_path)
|
||||
|
||||
print("STEP export completed successfully.")
|
||||
sys.exit(0)
|
||||
|
||||
except Exception as e:
|
||||
print(f"An error occurred during FreeCAD conversion: {e}")
|
||||
sys.exit(1)
|
||||
@ -1,41 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# --- export_dxf.sh ---
|
||||
# Exports a 2D projection of an OpenSCAD file to a DXF file.
|
||||
#
|
||||
# Usage: ./export_dxf.sh <source.scad> [output.dxf]
|
||||
#
|
||||
# Arguments:
|
||||
# $1: source_file - Input .scad file (Required)
|
||||
# $2: output_file - Output .dxf file (Optional)
|
||||
|
||||
# --- Input Validation ---
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 <source.scad> [output.dxf]"
|
||||
echo "Error: Source file not specified."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Argument Parsing ---
|
||||
SOURCE_FILE="$1"
|
||||
OUTPUT_FILE="$2"
|
||||
|
||||
# --- Set Default Output Filename ---
|
||||
if [ -z "$OUTPUT_FILE" ]; then
|
||||
OUTPUT_FILE="${SOURCE_FILE%.scad}_unfolded.dxf"
|
||||
fi
|
||||
|
||||
# --- OpenSCAD DXF Export Command ---
|
||||
echo "Exporting 2D projection from '$SOURCE_FILE' to '$OUTPUT_FILE'..."
|
||||
openscad \
|
||||
-o "$OUTPUT_FILE" \
|
||||
-D "view_mode=\"dxf\"" \
|
||||
"$SOURCE_FILE"
|
||||
|
||||
# --- Completion Message ---
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Export complete: '$OUTPUT_FILE' created successfully."
|
||||
else
|
||||
echo "Error: OpenSCAD DXF export failed."
|
||||
exit 1
|
||||
fi
|
||||
@ -1,44 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# --- export_freecad.sh ---
|
||||
# Imports an OpenSCAD file into FreeCAD and saves it as a .FCStd project.
|
||||
#
|
||||
# !! REQUIRES FREECAD & OPENSCAD WORKBENCH !!
|
||||
# This script depends on FreeCAD being installed, 'FreeCADCmd.exe'
|
||||
# being in your system's PATH, and the OpenSCAD workbench being installed
|
||||
# within FreeCAD.
|
||||
#
|
||||
# Usage: ./export_freecad.sh <source.scad> [output.FCStd]
|
||||
#
|
||||
# Arguments:
|
||||
# $1: source_file - Input .scad file (Required)
|
||||
# $2: output_file - Output .FCStd file (Optional)
|
||||
|
||||
# --- Input Validation ---
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 <source.scad> [output.FCStd]"
|
||||
echo "Error: Source file not specified."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Argument Parsing ---
|
||||
SOURCE_FILE="$1"
|
||||
OUTPUT_FILE="$2"
|
||||
|
||||
# --- Set Default Output Filename ---
|
||||
if [ -z "$OUTPUT_FILE" ]; then
|
||||
OUTPUT_FILE="${SOURCE_FILE%.scad}.FCStd"
|
||||
fi
|
||||
|
||||
# --- Step 1: Import .scad and save as .FCStd using FreeCAD ---
|
||||
echo "Importing '$SOURCE_FILE' and creating '$OUTPUT_FILE' using FreeCAD..."
|
||||
# Note: Assuming FreeCADCmd.exe for Windows. Use 'freecadcmd' on Linux.
|
||||
FreeCADCmd.exe -c save_fcstd.py "$SOURCE_FILE" "$OUTPUT_FILE"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: FreeCAD project creation failed. Is FreeCAD and the OpenSCAD workbench installed and in your PATH?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Completion Message ---
|
||||
echo "Export complete: '$OUTPUT_FILE' created successfully."
|
||||
@ -1,66 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# --- export_step.sh ---
|
||||
# Converts an OpenSCAD file to a STEP file using FreeCAD.
|
||||
#
|
||||
# !! REQUIRES FREECAD !!
|
||||
# This script depends on FreeCAD being installed and 'FreeCADCmd.exe'
|
||||
# being available in your system's PATH.
|
||||
#
|
||||
# Usage: ./export_step.sh <source.scad> [output.step]
|
||||
#
|
||||
# Arguments:
|
||||
# $1: source_file - Input .scad file (Required)
|
||||
# $2: output_file - Output .step file (Optional)
|
||||
|
||||
# --- Input Validation ---
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 <source.scad> [output.step]"
|
||||
echo "Error: Source file not specified."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Argument Parsing ---
|
||||
SOURCE_FILE="$1"
|
||||
OUTPUT_FILE="$2"
|
||||
|
||||
# --- Set Default Output Filename ---
|
||||
if [ -z "$OUTPUT_FILE" ]; then
|
||||
OUTPUT_FILE="${SOURCE_FILE%.scad}.step"
|
||||
fi
|
||||
|
||||
# --- Define Temporary STL file ---
|
||||
TEMP_STL_FILE="temp_conversion.stl"
|
||||
|
||||
# --- Step 1: Export from OpenSCAD to STL ---
|
||||
echo "Step 1/3: Exporting '$SOURCE_FILE' to STL using dedicated export layout..."
|
||||
openscad \
|
||||
-o "$TEMP_STL_FILE" \
|
||||
-D "view_mode=\"export\"" \
|
||||
"$SOURCE_FILE"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: OpenSCAD export failed."
|
||||
exit 1
|
||||
fi
|
||||
echo "STL export successful."
|
||||
|
||||
# --- Step 2: Convert STL to STEP using FreeCAD ---
|
||||
echo "Step 2/3: Converting '$TEMP_STL_FILE' to '$OUTPUT_FILE' using FreeCAD..."
|
||||
# Note: Assuming FreeCADCmd.exe for Windows. Use 'freecadcmd' on Linux.
|
||||
FreeCADCmd.exe -c converter.py "$TEMP_STL_FILE" "$OUTPUT_FILE"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: FreeCAD conversion failed. Is FreeCAD installed and in your PATH?"
|
||||
rm -f "$TEMP_STL_FILE" # Clean up temp file
|
||||
exit 1
|
||||
fi
|
||||
echo "STEP conversion successful."
|
||||
|
||||
# --- Step 3: Clean up temporary files ---
|
||||
echo "Step 3/3: Cleaning up temporary files..."
|
||||
rm -f "$TEMP_STL_FILE"
|
||||
echo "Done."
|
||||
|
||||
# --- Completion Message ---
|
||||
echo "Export complete: '$OUTPUT_FILE' created successfully."
|
||||
@ -1,59 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# --- export_stl.sh ---
|
||||
# Exports an OpenSCAD file to an STL file.
|
||||
#
|
||||
# Usage: ./export_stl.sh <source.scad> [output.stl] [folded_state]
|
||||
#
|
||||
# Arguments:
|
||||
# $1: source_file - Input .scad file (Required)
|
||||
# $2: output_file - Output .stl file (Optional)
|
||||
# $3: folded_state - 'true' or 'false'. (Optional, defaults to 'true' for a solid model)
|
||||
|
||||
# --- Input Validation ---
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 <source.scad> [output.stl] [folded_state]"
|
||||
echo "Error: Source file not specified."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Argument Parsing ---
|
||||
SOURCE_FILE="$1"
|
||||
OUTPUT_FILE=""
|
||||
# Default to 'true' as we usually want to export the assembled solid model
|
||||
FOLDED_STATE="true"
|
||||
|
||||
# Case 1: All three arguments are provided
|
||||
if [ -n "$3" ]; then
|
||||
OUTPUT_FILE="$2"
|
||||
FOLDED_STATE="$3"
|
||||
# Case 2: Only two arguments are provided
|
||||
elif [ -n "$2" ]; then
|
||||
# Check if the second argument is the folded state or a filename
|
||||
if [[ "$2" == "true" || "$2" == "false" ]]; then
|
||||
FOLDED_STATE="$2"
|
||||
else
|
||||
OUTPUT_FILE="$2"
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- Set Default Output Filename ---
|
||||
if [ -z "$OUTPUT_FILE" ]; then
|
||||
OUTPUT_FILE="${SOURCE_FILE%.scad}_${FOLDED_STATE}.stl"
|
||||
fi
|
||||
|
||||
# --- OpenSCAD Export Command ---
|
||||
# -D: Overrides a variable in the OpenSCAD script.
|
||||
echo "Exporting '$SOURCE_FILE' to '$OUTPUT_FILE' with Folded_View=$FOLDED_STATE..."
|
||||
openscad \
|
||||
-o "$OUTPUT_FILE" \
|
||||
-D "Folded_View=$FOLDED_STATE" \
|
||||
"$SOURCE_FILE"
|
||||
|
||||
# --- Completion Message ---
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Export complete: '$OUTPUT_FILE' created successfully."
|
||||
else
|
||||
echo "Error: OpenSCAD export failed."
|
||||
exit 1
|
||||
fi
|
||||
BIN
products/poly-mech/cad/drawers/tools/folded_view.png
(Stored with Git LFS)
BIN
products/poly-mech/cad/drawers/tools/folded_view.png
(Stored with Git LFS)
Binary file not shown.
@ -1,187 +0,0 @@
|
||||
# freecad_box_generator.py
|
||||
#
|
||||
# A Python script to generate a parametric box natively in FreeCAD.
|
||||
#
|
||||
# --- How to use (GUI) ---
|
||||
# 1. Open FreeCAD and ensure you have a new, empty document open.
|
||||
# 2. Paste this script into the Python console and press Enter.
|
||||
#
|
||||
# --- How to use (Command Line) ---
|
||||
# FreeCADCmd.exe freecad_box_generator.py [output_file.FCStd]
|
||||
|
||||
import FreeCAD
|
||||
import Part
|
||||
import sys
|
||||
|
||||
# --- Customizable Parameters ---
|
||||
# (Mirrors the parameters from the OpenSCAD file)
|
||||
|
||||
# Overall dimensions
|
||||
TOTAL_WIDTH = 500
|
||||
TOTAL_LENGTH = 500
|
||||
BOX_HEIGHT = 80
|
||||
|
||||
# Material and slot properties
|
||||
WALL_THICKNESS = 8
|
||||
|
||||
# Internal grid configuration
|
||||
NUM_BOXES_U = 2 # Along X-axis (width)
|
||||
NUM_BOXES_V = 2 # Along Y-axis (length)
|
||||
|
||||
|
||||
def create_box_assembly(doc):
|
||||
"""
|
||||
Generates the box assembly as native FreeCAD objects in the specified document.
|
||||
This function does not save the file.
|
||||
"""
|
||||
|
||||
# --- Create a Group for organization ---
|
||||
box_group = doc.addObject("App::DocumentObjectGroup", "BoxAssembly")
|
||||
|
||||
# --- Create the Base Plate ---
|
||||
base = Part.makeBox(TOTAL_WIDTH, TOTAL_LENGTH, WALL_THICKNESS)
|
||||
base_obj = doc.addObject("Part::Feature", "Base")
|
||||
base_obj.Shape = base
|
||||
box_group.addObject(base_obj)
|
||||
|
||||
# --- Calculate Inner Dimensions ---
|
||||
inner_width = TOTAL_WIDTH - (2 * WALL_THICKNESS)
|
||||
inner_length = TOTAL_LENGTH - (2 * WALL_THICKNESS)
|
||||
|
||||
# --- Create Outer Walls ---
|
||||
# South Wall (along the front X-axis)
|
||||
wall_south = Part.makeBox(TOTAL_WIDTH, WALL_THICKNESS, BOX_HEIGHT)
|
||||
wall_south.translate(FreeCAD.Vector(0, 0, WALL_THICKNESS)) # Position it on top of the base
|
||||
wall_south_obj = doc.addObject("Part::Feature", "Wall_South")
|
||||
wall_south_obj.Shape = wall_south
|
||||
box_group.addObject(wall_south_obj)
|
||||
|
||||
# North Wall (along the back X-axis)
|
||||
wall_north = Part.makeBox(TOTAL_WIDTH, WALL_THICKNESS, BOX_HEIGHT)
|
||||
wall_north.translate(FreeCAD.Vector(0, TOTAL_LENGTH - WALL_THICKNESS, WALL_THICKNESS))
|
||||
wall_north_obj = doc.addObject("Part::Feature", "Wall_North")
|
||||
wall_north_obj.Shape = wall_north
|
||||
box_group.addObject(wall_north_obj)
|
||||
|
||||
# West Wall (along the left Y-axis, fits between N/S walls)
|
||||
wall_west = Part.makeBox(WALL_THICKNESS, inner_length, BOX_HEIGHT)
|
||||
wall_west.translate(FreeCAD.Vector(0, WALL_THICKNESS, WALL_THICKNESS))
|
||||
wall_west_obj = doc.addObject("Part::Feature", "Wall_West")
|
||||
wall_west_obj.Shape = wall_west
|
||||
box_group.addObject(wall_west_obj)
|
||||
|
||||
# East Wall (along the right Y-axis, fits between N/S walls)
|
||||
wall_east = Part.makeBox(WALL_THICKNESS, inner_length, BOX_HEIGHT)
|
||||
wall_east.translate(FreeCAD.Vector(TOTAL_WIDTH - WALL_THICKNESS, WALL_THICKNESS, WALL_THICKNESS))
|
||||
wall_east_obj = doc.addObject("Part::Feature", "Wall_East")
|
||||
wall_east_obj.Shape = wall_east
|
||||
box_group.addObject(wall_east_obj)
|
||||
|
||||
# --- Create Internal Dividers ---
|
||||
if NUM_BOXES_U > 1:
|
||||
# --- Vertical Dividers (along Y-axis) ---
|
||||
compartment_width = inner_width / NUM_BOXES_U
|
||||
for i in range(1, NUM_BOXES_U):
|
||||
# Create the main body of the divider
|
||||
x_pos = (i * compartment_width)
|
||||
divider_v_body = Part.makeBox(WALL_THICKNESS, inner_length, BOX_HEIGHT)
|
||||
|
||||
# --- Create Notches for Horizontal Dividers (top-down) ---
|
||||
if NUM_BOXES_V > 1:
|
||||
# Create all notch cutting tools first
|
||||
notch_tools = []
|
||||
notch_cutout = Part.makeBox(WALL_THICKNESS, WALL_THICKNESS, BOX_HEIGHT / 2)
|
||||
for j in range(1, NUM_BOXES_V):
|
||||
compartment_length = inner_length / NUM_BOXES_V
|
||||
y_pos = (j * compartment_length) - (WALL_THICKNESS / 2)
|
||||
notch_tools.append(notch_cutout.translated(FreeCAD.Vector(0, y_pos, BOX_HEIGHT / 2)))
|
||||
# Fuse them into a single cutting tool
|
||||
cutting_compound = Part.makeCompound(notch_tools)
|
||||
# Perform a single, efficient cut
|
||||
divider_v_body = divider_v_body.cut(cutting_compound)
|
||||
|
||||
# Position the final divider and add to document
|
||||
divider_v_body.translate(FreeCAD.Vector(x_pos, WALL_THICKNESS, WALL_THICKNESS))
|
||||
divider_v_obj = doc.addObject("Part::Feature", f"Divider_V_{i}")
|
||||
divider_v_obj.Shape = divider_v_body
|
||||
box_group.addObject(divider_v_obj)
|
||||
|
||||
if NUM_BOXES_V > 1:
|
||||
# --- Horizontal Dividers (along X-axis) ---
|
||||
compartment_length = inner_length / NUM_BOXES_V
|
||||
for i in range(1, NUM_BOXES_V):
|
||||
# Create the main body of the divider
|
||||
y_pos = (i * compartment_length)
|
||||
divider_h_body = Part.makeBox(inner_width, WALL_THICKNESS, BOX_HEIGHT)
|
||||
|
||||
# --- Create Notches for Vertical Dividers (bottom-up) ---
|
||||
if NUM_BOXES_U > 1:
|
||||
# Create all notch cutting tools first
|
||||
notch_tools = []
|
||||
notch_cutout = Part.makeBox(WALL_THICKNESS, WALL_THICKNESS, BOX_HEIGHT / 2)
|
||||
for j in range(1, NUM_BOXES_U):
|
||||
compartment_width = inner_width / NUM_BOXES_U
|
||||
x_pos = (j * compartment_width) - (WALL_THICKNESS / 2)
|
||||
notch_tools.append(notch_cutout.translated(FreeCAD.Vector(x_pos, 0, 0)))
|
||||
# Fuse them into a single cutting tool
|
||||
cutting_compound = Part.makeCompound(notch_tools)
|
||||
# Perform a single, efficient cut
|
||||
divider_h_body = divider_h_body.cut(cutting_compound)
|
||||
|
||||
# Position the final divider and add to document
|
||||
divider_h_body.translate(FreeCAD.Vector(WALL_THICKNESS, y_pos, WALL_THICKNESS))
|
||||
divider_h_obj = doc.addObject("Part::Feature", f"Divider_H_{i}")
|
||||
divider_h_obj.Shape = divider_h_body
|
||||
box_group.addObject(divider_h_obj)
|
||||
|
||||
# --- Finalize ---
|
||||
doc.recompute()
|
||||
print("Box assembly generated.")
|
||||
|
||||
|
||||
def main_cli():
|
||||
"""Function to run when script is executed from the command line."""
|
||||
output_file = "box.FCStd" # Default filename
|
||||
|
||||
# Look for the output file as a positional argument after the script name
|
||||
# This is a robust way to handle arguments when FreeCAD's parser is unpredictable.
|
||||
try:
|
||||
script_index = [i for i, arg in enumerate(sys.argv) if 'freecad_box_generator.py' in arg][0]
|
||||
if script_index + 1 < len(sys.argv):
|
||||
output_file = sys.argv[script_index + 1]
|
||||
except IndexError:
|
||||
# This case handles running the script directly without FreeCAD, for debugging.
|
||||
pass
|
||||
|
||||
doc = FreeCAD.newDocument("Box")
|
||||
create_box_assembly(doc)
|
||||
|
||||
try:
|
||||
doc.saveAs(output_file)
|
||||
print(f"Successfully saved box assembly to: {output_file}")
|
||||
except Exception as e:
|
||||
print(f"Error saving file: {e}")
|
||||
|
||||
FreeCAD.closeDocument(doc.Name)
|
||||
# Ensure the command-line application exits cleanly
|
||||
sys.exit()
|
||||
|
||||
def main_gui():
|
||||
"""Function to run when script is executed from the FreeCAD GUI."""
|
||||
doc = FreeCAD.activeDocument()
|
||||
if not doc:
|
||||
doc = FreeCAD.newDocument("Box")
|
||||
|
||||
create_box_assembly(doc)
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
FreeCAD.Gui.activeDocument().activeView().viewAxonometric()
|
||||
FreeCAD.Gui.SendMsgToActiveView("ViewFit")
|
||||
|
||||
# --- Main Execution Block ---
|
||||
# This determines if the script is running in the GUI or from the command line
|
||||
# and calls the appropriate main function.
|
||||
if FreeCAD.GuiUp:
|
||||
main_gui()
|
||||
else:
|
||||
main_cli()
|
||||
Binary file not shown.
@ -1,31 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# --- run_freecad_generator.sh ---
|
||||
#
|
||||
# A wrapper script to correctly call the FreeCAD box generator from the command line.
|
||||
#
|
||||
# Usage: ./run_freecad_generator.sh <output_file.FCStd>
|
||||
|
||||
# --- Argument Validation ---
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 <output_file.FCStd>"
|
||||
echo "Error: Output file not specified."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OUTPUT_FILE="$1"
|
||||
|
||||
# --- Execute FreeCAD ---
|
||||
# We pass the python script to the FreeCAD executable, followed by the
|
||||
# output filename as a simple positional argument.
|
||||
|
||||
echo "Executing FreeCAD generator script..."
|
||||
FreeCADCmd.exe -c freecad_box_generator.py "$OUTPUT_FILE"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo ""
|
||||
echo "Error: FreeCAD script execution failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Script executed successfully."
|
||||
@ -1,41 +0,0 @@
|
||||
# save_fcstd.py
|
||||
# A Python script for use with FreeCAD's command-line interface.
|
||||
# Imports an OpenSCAD file and saves it as a FreeCAD project.
|
||||
|
||||
import sys
|
||||
import FreeCAD
|
||||
import Part
|
||||
|
||||
# --- Argument Validation ---
|
||||
if len(sys.argv) < 3:
|
||||
print("Converter script usage: <input_file.scad> <output_file.FCStd>")
|
||||
sys.exit(1)
|
||||
|
||||
input_file_path = sys.argv[-2]
|
||||
output_file_path = sys.argv[-1]
|
||||
|
||||
print(f"Input file: {input_file_path}")
|
||||
print(f"Output file: {output_file_path}")
|
||||
|
||||
# --- Conversion Logic ---
|
||||
try:
|
||||
# 1. Create a new, empty FreeCAD document
|
||||
doc = FreeCAD.newDocument("ImportedSCAD")
|
||||
|
||||
# 2. Use the Part module to import the .scad file into the document.
|
||||
# This requires the OpenSCAD workbench to be installed in FreeCAD.
|
||||
# FreeCAD manages the call to the 'openscad' executable itself.
|
||||
Part.insert(input_file_path, doc.Name)
|
||||
|
||||
# 3. It's good practice to recompute the model after an import.
|
||||
doc.recompute()
|
||||
|
||||
# 4. Save the document to the specified output file path.
|
||||
doc.saveAs(output_file_path)
|
||||
|
||||
print("FreeCAD project file saved successfully.")
|
||||
sys.exit(0)
|
||||
|
||||
except Exception as e:
|
||||
print(f"An error occurred during FreeCAD project creation: {e}")
|
||||
sys.exit(1)
|
||||
@ -1,52 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# --- generate_cut_plan.sh ---
|
||||
# Generates a markdown cut plan from an OpenSCAD file.
|
||||
# This script calls OpenSCAD in a special mode to echo the plan.
|
||||
#
|
||||
# Usage: ./generate_cut_plan.sh <source.scad> [output.md]
|
||||
# If output file is not provided, prints to console.
|
||||
|
||||
# --- Input Validation ---
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 <source.scad> [output.md]"
|
||||
echo "Error: Source file not specified."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SOURCE_FILE="$1"
|
||||
OUTPUT_FILE="$2"
|
||||
DUMMY_OUTPUT="cutplan_dummy.stl" # A dummy file to force command-line execution
|
||||
|
||||
# --- OpenSCAD Command ---
|
||||
# We force a dummy output file with -o to prevent the GUI from launching.
|
||||
# OpenSCAD prints echo() statements to stderr. We redirect stderr to stdout (2>&1),
|
||||
# then use grep to filter for only the lines starting with "ECHO:",
|
||||
# and then use sed to remove the prefix and surrounding quotes for a clean output.
|
||||
CUTPLAN_CONTENT=$(openscad \
|
||||
-o "$DUMMY_OUTPUT" \
|
||||
-D "view_mode=\"cutplan\"" \
|
||||
"$SOURCE_FILE" \
|
||||
2>&1 | grep "ECHO:" | sed 's/ECHO: "//;s/"$//')
|
||||
|
||||
# Check the exit status of the openscad command.
|
||||
if [ ${PIPESTATUS[0]} -ne 0 ]; then
|
||||
echo ""
|
||||
echo "Error: OpenSCAD command failed."
|
||||
rm -f "$DUMMY_OUTPUT" # Clean up dummy file on failure
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clean up the dummy file
|
||||
rm -f "$DUMMY_OUTPUT"
|
||||
|
||||
# --- Output the result ---
|
||||
if [ -z "$OUTPUT_FILE" ]; then
|
||||
echo ""
|
||||
echo "--- Generated Cut Plan (Markdown) ---"
|
||||
echo "$CUTPLAN_CONTENT"
|
||||
echo "-------------------------------------"
|
||||
else
|
||||
echo "$CUTPLAN_CONTENT" > "$OUTPUT_FILE"
|
||||
echo "Cut plan successfully saved to '$OUTPUT_FILE'."
|
||||
fi
|
||||
@ -1,34 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# --- generate_cutlist.sh ---
|
||||
# Generates a markdown cut plan by calling an external Python script.
|
||||
# This bypasses a bug in some OpenSCAD versions that prevents the echo
|
||||
# module from functioning correctly.
|
||||
#
|
||||
# Usage: ./generate_cutlist.sh [output.md]
|
||||
# All parameters are taken from the defaults in the python script.
|
||||
# For custom dimensions, edit calculate_cuts.py or call it directly.
|
||||
|
||||
OUTPUT_FILE="$1"
|
||||
|
||||
# Run the python script to generate the markdown content.
|
||||
# The script can be modified to change box parameters.
|
||||
CUTLIST_CONTENT=$(python calculate_cuts.py)
|
||||
|
||||
# Check the exit status of the python script.
|
||||
if [ $? -ne 0 ]; then
|
||||
echo ""
|
||||
echo "Error: Python script 'calculate_cuts.py' failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Output the result ---
|
||||
if [ -z "$OUTPUT_FILE" ]; then
|
||||
echo ""
|
||||
echo "--- Generated Cut Plan (Markdown) ---"
|
||||
echo "$CUTLIST_CONTENT"
|
||||
echo "-------------------------------------"
|
||||
else
|
||||
echo "$CUTLIST_CONTENT" > "$OUTPUT_FILE"
|
||||
echo "Cut plan successfully saved to '$OUTPUT_FILE'."
|
||||
fi
|
||||
BIN
products/poly-mech/cad/drawers/tools/reference/500-10.png
(Stored with Git LFS)
BIN
products/poly-mech/cad/drawers/tools/reference/500-10.png
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/drawers/tools/reference/variables.png
(Stored with Git LFS)
BIN
products/poly-mech/cad/drawers/tools/reference/variables.png
(Stored with Git LFS)
Binary file not shown.
@ -1,64 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# --- render.sh ---
|
||||
# Renders an OpenSCAD file to a PNG image.
|
||||
#
|
||||
# Usage: ./render.sh <source_file.scad> [output_file.png] [folded_state]
|
||||
#
|
||||
# Arguments:
|
||||
# $1: source_file - The path to the input OpenSCAD file. (Required)
|
||||
# $2: output_file - The path for the output PNG image. (Optional)
|
||||
# $3: folded_state - 'true' or 'false' to control the Folded_View parameter.
|
||||
# (Optional, defaults to false)
|
||||
|
||||
# --- Input Validation ---
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 <source_file.scad> [output_file.png] [folded_state]"
|
||||
echo "Error: Source file not specified."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Argument Parsing ---
|
||||
SOURCE_FILE="$1"
|
||||
OUTPUT_FILE=""
|
||||
FOLDED_STATE="false" # Default value
|
||||
|
||||
# Case 1: All three arguments are provided
|
||||
if [ -n "$3" ]; then
|
||||
OUTPUT_FILE="$2"
|
||||
FOLDED_STATE="$3"
|
||||
# Case 2: Only two arguments are provided
|
||||
elif [ -n "$2" ]; then
|
||||
# Check if the second argument is the folded state or a filename
|
||||
if [[ "$2" == "true" || "$2" == "false" ]]; then
|
||||
FOLDED_STATE="$2"
|
||||
else
|
||||
OUTPUT_FILE="$2"
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- Set Default Output Filename ---
|
||||
if [ -z "$OUTPUT_FILE" ]; then
|
||||
# Removes the .scad extension and appends .png
|
||||
OUTPUT_FILE="${SOURCE_FILE%.scad}_${FOLDED_STATE}.png"
|
||||
fi
|
||||
|
||||
# --- OpenSCAD Render Command ---
|
||||
# --view=iso: Sets the camera to a standard isometric view.
|
||||
# --imgsize: Sets the output image resolution.
|
||||
# -D: Overrides a variable in the OpenSCAD script.
|
||||
echo "Rendering '$SOURCE_FILE' to '$OUTPUT_FILE' with Folded_View=$FOLDED_STATE..."
|
||||
openscad \
|
||||
-o "$OUTPUT_FILE" \
|
||||
--view=iso \
|
||||
--imgsize=1024,768 \
|
||||
-D "Folded_View=$FOLDED_STATE" \
|
||||
"$SOURCE_FILE"
|
||||
|
||||
# --- Completion Message ---
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Render complete: '$OUTPUT_FILE' created successfully."
|
||||
else
|
||||
echo "Error: OpenSCAD rendering failed."
|
||||
exit 1
|
||||
fi
|
||||
@ -1,151 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using CommandLine;
|
||||
using SolidWorks.Interop.sldworks;
|
||||
using SolidWorks.Interop.swconst;
|
||||
|
||||
namespace SolidWorksBoxGenerator
|
||||
{
|
||||
// Class to hold the parsed command-line options
|
||||
public class Options
|
||||
{
|
||||
[Option('o', "output", Required = true, HelpText = "Absolute path for the output .SLDPRT file.")]
|
||||
public string OutputFile { get; set; }
|
||||
|
||||
[Option('w', "width", Default = 500.0, HelpText = "Total width of the box.")]
|
||||
public double Width { get; set; }
|
||||
|
||||
[Option('l', "length", Default = 500.0, HelpText = "Total length of the box.")]
|
||||
public double Length { get; set; }
|
||||
|
||||
[Option('h', "height", Default = 80.0, HelpText = "Height of the box walls.")]
|
||||
public double Height { get; set; }
|
||||
|
||||
[Option('t', "thickness", Default = 3.0, HelpText = "Sheet metal thickness.")]
|
||||
public double Thickness { get; set; }
|
||||
|
||||
[Option('r', "radius", Default = 1.0, HelpText = "Bend radius for sheet metal.")]
|
||||
public double Radius { get; set; }
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Parser.Default.ParseArguments<Options>(args)
|
||||
.WithParsed<Options>(o =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine("Attempting to connect to SolidWorks...");
|
||||
SldWorks swApp = GetSldWorks();
|
||||
if (swApp == null)
|
||||
{
|
||||
Console.WriteLine("Could not connect to SolidWorks. Please ensure it is running.");
|
||||
return;
|
||||
}
|
||||
Console.WriteLine("Successfully connected to SolidWorks.");
|
||||
|
||||
GenerateBox(swApp, o);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine($"An error occurred: {e.Message}");
|
||||
Console.WriteLine(e.StackTrace);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static SldWorks GetSldWorks()
|
||||
{
|
||||
// Connect to a running instance of SolidWorks
|
||||
try
|
||||
{
|
||||
return (SldWorks)Marshal.GetActiveObject("SldWorks.Application");
|
||||
}
|
||||
catch (COMException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void GenerateBox(SldWorks swApp, Options opts)
|
||||
{
|
||||
// Convert all measurements from mm to meters for SolidWorks
|
||||
double width = opts.Width / 1000.0;
|
||||
double length = opts.Length / 1000.0;
|
||||
double height = opts.Height / 1000.0;
|
||||
double thickness = opts.Thickness / 1000.0;
|
||||
double radius = opts.Radius / 1000.0;
|
||||
|
||||
// --- Step 1: Create a New Part Document ---
|
||||
Console.WriteLine("Creating new part document...");
|
||||
ModelDoc2 swModel = (ModelDoc2)swApp.NewPart();
|
||||
if (swModel == null)
|
||||
{
|
||||
Console.WriteLine("Failed to create new part.");
|
||||
return;
|
||||
}
|
||||
|
||||
FeatureManager featMan = swModel.FeatureManager;
|
||||
SketchManager skMan = swModel.SketchManager;
|
||||
swModel.ClearSelection2(true);
|
||||
|
||||
// --- Step 2: Create the Base Flange ---
|
||||
Console.WriteLine("Creating base flange...");
|
||||
// Select the Top Plane (defined as "Plane3" internally by the API)
|
||||
swModel.Extension.SelectByID2("Plane3", "PLANE", 0, 0, 0, false, 0, null, 0);
|
||||
skMan.InsertSketch(true);
|
||||
skMan.CreateCenterRectangle(0, 0, 0, width / 2, length / 2, 0);
|
||||
skMan.InsertSketch(true);
|
||||
|
||||
Feature sheetMetalFeature = featMan.InsertSheetMetalBaseFlange2(thickness, false, radius, 0, 0, 0, 0.5, 0, 0, 0, false, false, false, false);
|
||||
if(sheetMetalFeature == null)
|
||||
{
|
||||
Console.WriteLine("Failed to create base flange.");
|
||||
swApp.CloseDoc(swModel.GetTitle());
|
||||
return;
|
||||
}
|
||||
swModel.ClearSelection2(true);
|
||||
|
||||
// --- Step 3: Create Edge Flanges (Walls) ---
|
||||
Console.WriteLine("Creating edge flanges for walls...");
|
||||
object[] edges = new object[4];
|
||||
edges[0] = GetEdgeByVertex(swModel, width / 2, length / 2, 0); // Front-Right edge
|
||||
edges[1] = GetEdgeByVertex(swModel, -width / 2, length / 2, 0); // Front-Left edge
|
||||
edges[2] = GetEdgeByVertex(swModel, -width / 2, -length / 2, 0); // Back-Left edge
|
||||
edges[3] = GetEdgeByVertex(swModel, width / 2, -length / 2, 0); // Back-Right edge
|
||||
|
||||
// Selecting all 4 edges at once to create mitered corners automatically
|
||||
swModel.Extension.SelectByID2(((IEntity)edges[0]).GetSelectionId(), "EDGE", 0,0,0, true, 1, null, 0);
|
||||
swModel.Extension.SelectByID2(((IEntity)edges[1]).GetSelectionId(), "EDGE", 0,0,0, true, 1, null, 0);
|
||||
swModel.Extension.SelectByID2(((IEntity)edges[2]).GetSelectionId(), "EDGE", 0,0,0, true, 1, null, 0);
|
||||
swModel.Extension.SelectByID2(((IEntity)edges[3]).GetSelectionId(), "EDGE", 0,0,0, true, 1, null, 0);
|
||||
|
||||
featMan.InsertSheetMetalEdgeFlange(height, radius, (90.0 * Math.PI / 180.0), (int)swSheetMetalFlangeLengthMethod_e.swSheetMetalFlangeLengthMethod_OuterVirtualSharp, 0, (int)swSheetMetalFlangePosition_e.swSheetMetalFlangePosition_MaterialInside, false, 0, 0, 0, 0, false, false);
|
||||
swModel.ClearSelection2(true);
|
||||
|
||||
// --- Step 4: Save and Close ---
|
||||
Console.WriteLine($"Saving file to {opts.OutputFile}...");
|
||||
bool saveSuccess = swModel.Extension.SaveAs(opts.OutputFile, (int)swSaveAsVersion_e.swSaveAsCurrentVersion, (int)swSaveAsOptions_e.swSaveAsOptions_Silent, null, 0, 0);
|
||||
|
||||
if (saveSuccess)
|
||||
{
|
||||
Console.WriteLine("File saved successfully.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Failed to save the file.");
|
||||
}
|
||||
swApp.CloseDoc(swModel.GetTitle());
|
||||
}
|
||||
|
||||
// Helper function to find an edge based on one of its vertices' coordinates
|
||||
private static IEdge GetEdgeByVertex(ModelDoc2 model, double x, double y, double z)
|
||||
{
|
||||
var body = ((PartDoc)model).GetBodies2((int)swBodyType_e.swSolidBody, true)[0] as IBody2;
|
||||
var vertex = body.GetFinniestVertex(x,y,z) as IVertex;
|
||||
return vertex.GetEdges()[0] as IEdge;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,38 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!--
|
||||
This is a reference to the main SolidWorks Interop Assembly.
|
||||
You MUST update the HintPath to match the location of this file on your system.
|
||||
It is typically in the SolidWorks installation directory.
|
||||
-->
|
||||
<Reference Include="SolidWorks.Interop.sldworks">
|
||||
<HintPath>C:\Program Files\SOLIDWORKS Corp\SOLIDWORKS\api\redist\SolidWorks.Interop.sldworks.dll</HintPath>
|
||||
<EmbedInteropTypes>true</EmbedInteropTypes>
|
||||
</Reference>
|
||||
<!--
|
||||
This is a reference to the SolidWorks constants Interop Assembly.
|
||||
Update the HintPath to match the location of this file on your system.
|
||||
-->
|
||||
<Reference Include="SolidWorks.Interop.swconst">
|
||||
<HintPath>C:\Program Files\SOLIDWORKS Corp\SOLIDWORKS\api\redist\SolidWorks.Interop.swconst.dll</HintPath>
|
||||
<EmbedInteropTypes>true</EmbedInteropTypes>
|
||||
</Reference>
|
||||
<!-- A reference for standard COM marshalling -->
|
||||
<Reference Include="System"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- This adds a popular library for parsing command-line arguments -->
|
||||
<PackageReference Include="CommandLineParser" Version="2.9.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@ -1,100 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const yargs = require('yargs/yargs');
|
||||
const { hideBin } = require('yargs/helpers');
|
||||
const { spawn } = require('child_process');
|
||||
const path = require('path');
|
||||
|
||||
// --- Command-Line Interface Definition ---
|
||||
const argv = yargs(hideBin(process.argv))
|
||||
.command(
|
||||
'$0 [output]',
|
||||
'Generate a parametric sheet metal box in SolidWorks',
|
||||
(yargs) => {
|
||||
return yargs
|
||||
.positional('output', {
|
||||
describe: 'Absolute path to the output .SLDPRT file. Defaults to a file in your Documents folder.',
|
||||
default: path.join(require('os').homedir(), 'Documents', 'sw-generated-box.SLDPRT')
|
||||
});
|
||||
}
|
||||
)
|
||||
.option('width', {
|
||||
alias: 'w',
|
||||
type: 'number',
|
||||
description: 'Total width of the box',
|
||||
default: 500
|
||||
})
|
||||
.option('length', {
|
||||
alias: 'l',
|
||||
type: 'number',
|
||||
description: 'Total length of the box',
|
||||
default: 500
|
||||
})
|
||||
.option('height', {
|
||||
alias: 'h',
|
||||
type: 'number',
|
||||
description: 'Height of the box walls',
|
||||
default: 80
|
||||
})
|
||||
.option('thickness', {
|
||||
alias: 't',
|
||||
type: 'number',
|
||||
description: 'Sheet metal thickness',
|
||||
default: 3
|
||||
})
|
||||
.option('radius', {
|
||||
alias: 'r',
|
||||
type: 'number',
|
||||
description: 'Bend radius for sheet metal',
|
||||
default: 1
|
||||
})
|
||||
.help()
|
||||
.argv;
|
||||
|
||||
// --- Constructing the Arguments for the C# Application ---
|
||||
|
||||
// Path to the C# executable. We assume it's in './sw/box/bin/Debug/net48/SolidWorksBoxGenerator.exe'
|
||||
// You may need to adjust the '.net48' folder depending on your target framework version.
|
||||
const generatorExePath = path.resolve(__dirname, '..', 'box', 'bin', 'Debug', 'net48', 'SolidWorksBoxGenerator.exe');
|
||||
|
||||
// The C# app expects arguments in the format "--key value"
|
||||
const generatorArgs = [
|
||||
'--output', argv.output,
|
||||
'--width', argv.width,
|
||||
'--length', argv.length,
|
||||
'--height', argv.height,
|
||||
'--thickness', argv.thickness,
|
||||
'--radius', argv.radius
|
||||
];
|
||||
|
||||
// --- Executing the C# Application ---
|
||||
|
||||
console.log('Executing SolidWorks Box Generator...');
|
||||
console.log(`Command: "${generatorExePath}" ${generatorArgs.join(' ')}`);
|
||||
|
||||
try {
|
||||
const generatorProcess = spawn(generatorExePath, generatorArgs);
|
||||
|
||||
generatorProcess.stdout.on('data', (data) => {
|
||||
// Trim whitespace from generator output for cleaner logging
|
||||
process.stdout.write(`[Generator]: ${data.toString().trim()}\n`);
|
||||
});
|
||||
|
||||
generatorProcess.stderr.on('data', (data) => {
|
||||
console.error(`[Generator ERROR]: ${data}`);
|
||||
});
|
||||
|
||||
generatorProcess.on('close', (code) => {
|
||||
console.log(`\nGenerator process exited with code ${code}`);
|
||||
if (code !== 0) {
|
||||
console.error("Box generation failed. Ensure SolidWorks is running.");
|
||||
} else {
|
||||
console.log(`Box generation complete. File saved to: ${argv.output}`);
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error(`Failed to start the generator process. Make sure the C# project has been built.`);
|
||||
console.error(`Expected executable at: ${generatorExePath}`);
|
||||
console.error(error);
|
||||
}
|
||||
@ -1,196 +0,0 @@
|
||||
{
|
||||
"name": "solidworks-box-generator-cli",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "solidworks-box-generator-cli",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"yargs": "^17.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"generate-box": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
},
|
||||
"node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "solidworks-box-generator-cli",
|
||||
"version": "1.0.0",
|
||||
"description": "A CLI for generating boxes in SolidWorks.",
|
||||
"main": "cli.js",
|
||||
"bin": {
|
||||
"generate-box": "./cli.js"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node cli.js",
|
||||
"build": "echo 'Build step not required for this simple CLI. Linting or packaging could go here.'"
|
||||
},
|
||||
"dependencies": {
|
||||
"yargs": "^17.0.0"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
||||
@ -1,348 +0,0 @@
|
||||
// Customizable parameters for the box folding tool
|
||||
// These values are based on the provided screenshot.
|
||||
|
||||
// Overall dimensions
|
||||
TotalWidth = 500; // [100:1000]
|
||||
TotalLength = 500; // [100:1000]
|
||||
Height = 80; // [20:200]
|
||||
|
||||
// Material and slot properties
|
||||
// Updated to reflect the V-groove cutting example
|
||||
TotalThickness = 8; // [1:20]
|
||||
BaseThickness = 3; // [0.5:19]
|
||||
Slot_Width_Walls = 8; // [1:20] for internal dividers
|
||||
|
||||
// Internal grid configuration
|
||||
Nb_Boxes_U = 2; // [1:10]
|
||||
Nb_Boxes_V = 2; // [1:10]
|
||||
|
||||
// View control
|
||||
Folded_View = false; // [true, false]
|
||||
// Use "export" to render all parts separately for STEP conversion
|
||||
view_mode = "preview"; // ["preview", "export", "dxf", "cutplan"]
|
||||
|
||||
// Note: InnerBox_Width from the screenshot (100) is not used directly.
|
||||
// Instead, the compartment widths are calculated based on TotalWidth, Height, and Nb_Boxes_U/V.
|
||||
// This ensures the design remains consistent with the overall dimensions.
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Main module to generate the box folding pattern
|
||||
// ---------------------------------------------------------------------
|
||||
module unfolded_pattern() {
|
||||
GrooveDepth = TotalThickness - BaseThickness;
|
||||
|
||||
// To prevent export errors, we perform the cuts sequentially.
|
||||
// This is more stable than a single, complex difference().
|
||||
difference() {
|
||||
// Start with the result of the first cut...
|
||||
difference() {
|
||||
// 1. Create the base plate
|
||||
cube([TotalWidth, TotalLength, TotalThickness], center = true);
|
||||
|
||||
// 2. Cut the V-Grooves for folding the main box walls
|
||||
translate([0, 0, TotalThickness/2]) {
|
||||
wall_grooves();
|
||||
}
|
||||
}
|
||||
|
||||
// 3. ...and then cut the internal rectangular slots from that result.
|
||||
if (Nb_Boxes_U > 1 || Nb_Boxes_V > 1) {
|
||||
translate([0,0,TotalThickness/2 - GrooveDepth/2])
|
||||
internal_grooves();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Helper modules
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
// Module for creating the grooves for the outer walls
|
||||
// Reverted to simple rectangular slots as a final workaround to bypass
|
||||
// a persistent, unfixable geometry kernel bug with V-grooves.
|
||||
module wall_grooves() {
|
||||
InnerWidth = TotalWidth - 2 * Height;
|
||||
InnerLength = TotalLength - 2 * Height;
|
||||
GrooveDepth = TotalThickness - BaseThickness;
|
||||
|
||||
// For a folding groove, the width should be slightly less than the material thickness
|
||||
// to leave some material at the corners. We'll use the depth as a proxy.
|
||||
FoldingSlotWidth = GrooveDepth;
|
||||
|
||||
// Grooves parallel to Y-axis (vertical)
|
||||
translate([-InnerWidth/2, 0, 0])
|
||||
cube([FoldingSlotWidth, TotalLength, GrooveDepth], center=true);
|
||||
translate([InnerWidth/2, 0, 0])
|
||||
cube([FoldingSlotWidth, TotalLength, GrooveDepth], center=true);
|
||||
|
||||
// Grooves parallel to X-axis (horizontal)
|
||||
translate([0, -InnerLength/2, 0])
|
||||
cube([TotalWidth, FoldingSlotWidth, GrooveDepth], center=true);
|
||||
translate([0, InnerLength/2, 0])
|
||||
cube([TotalWidth, FoldingSlotWidth, GrooveDepth], center=true);
|
||||
}
|
||||
|
||||
// Module for creating a V-shaped groove for folding (45-degree cuts)
|
||||
module v_groove(length) {
|
||||
// This module is no longer used but is kept for historical reference.
|
||||
}
|
||||
|
||||
// Module for creating the grooves for the internal compartments
|
||||
module internal_grooves() {
|
||||
InnerWidth = TotalWidth - 2 * Height;
|
||||
InnerLength = TotalLength - 2 * Height;
|
||||
GrooveDepth = TotalThickness - BaseThickness;
|
||||
|
||||
CompartmentWidth = (InnerWidth - (Nb_Boxes_U - 1) * Slot_Width_Walls) / Nb_Boxes_U;
|
||||
CompartmentLength = (InnerLength - (Nb_Boxes_V - 1) * Slot_Width_Walls) / Nb_Boxes_V;
|
||||
|
||||
// Internal vertical grooves
|
||||
if (Nb_Boxes_U > 1) {
|
||||
for (i = [1 : Nb_Boxes_U - 1]) {
|
||||
x_pos = -InnerWidth/2 + i * CompartmentWidth + (i - 1/2) * Slot_Width_Walls;
|
||||
translate([x_pos, 0, 0])
|
||||
cube([Slot_Width_Walls, InnerLength, GrooveDepth], center = true);
|
||||
}
|
||||
}
|
||||
|
||||
// Internal horizontal grooves
|
||||
if (Nb_Boxes_V > 1) {
|
||||
for (i = [1 : Nb_Boxes_V - 1]) {
|
||||
y_pos = -InnerLength/2 + i * CompartmentLength + (i - 1/2) * Slot_Width_Walls;
|
||||
translate([0, y_pos, 0])
|
||||
cube([InnerWidth, Slot_Width_Walls, GrooveDepth], center = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Modules for Folded View
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
// Generates the fully assembled 3D box
|
||||
module folded_box() {
|
||||
// Inner dimensions of the box
|
||||
InnerWidth = TotalWidth - 2 * Height;
|
||||
InnerLength = TotalLength - 2 * Height;
|
||||
|
||||
// Material thickness for all parts
|
||||
wall_thickness = TotalThickness;
|
||||
|
||||
// 1. Base Plate
|
||||
translate([0, 0, wall_thickness / 2])
|
||||
cube([InnerWidth, InnerLength, wall_thickness], center = true);
|
||||
|
||||
// 2. Outer Walls
|
||||
// South Wall (bottom) - Full Width
|
||||
translate([0, -InnerLength/2, Height/2 + wall_thickness])
|
||||
rotate([90, 0, 0])
|
||||
cube([InnerWidth, Height, wall_thickness], center=true);
|
||||
|
||||
// North Wall (top) - Full Width
|
||||
translate([0, InnerLength/2, Height/2 + wall_thickness])
|
||||
rotate([-90, 0, 0])
|
||||
cube([InnerWidth, Height, wall_thickness], center=true);
|
||||
|
||||
// West Wall (left) - Shortened to fit between North/South walls
|
||||
translate([-InnerWidth/2, 0, Height/2 + wall_thickness])
|
||||
rotate([0, 90, 0])
|
||||
cube([Height, InnerLength - 2 * wall_thickness, wall_thickness], center=true);
|
||||
|
||||
// East Wall (right) - Shortened to fit between North/South walls
|
||||
translate([InnerWidth/2, 0, Height/2 + wall_thickness])
|
||||
rotate([0, -90, 0])
|
||||
cube([Height, InnerLength - 2 * wall_thickness, wall_thickness], center=true);
|
||||
|
||||
// 3. Internal Dividers
|
||||
internal_dividers_folded();
|
||||
}
|
||||
|
||||
// Generates the interlocking internal dividers for the folded view
|
||||
module internal_dividers_folded() {
|
||||
InnerWidth = TotalWidth - 2 * Height;
|
||||
InnerLength = TotalLength - 2 * Height;
|
||||
divider_thickness = Slot_Width_Walls; // Use slot width as the divider material thickness
|
||||
|
||||
// Calculate compartment sizes
|
||||
Compartment_U = (InnerWidth + divider_thickness) / Nb_Boxes_U;
|
||||
Compartment_V = (InnerLength + divider_thickness) / Nb_Boxes_V;
|
||||
|
||||
// Vertical dividers (U-direction)
|
||||
for (i = [1 : Nb_Boxes_U - 1]) {
|
||||
x_pos = -InnerWidth/2 + i * Compartment_U - divider_thickness/2;
|
||||
difference() {
|
||||
// Main divider piece
|
||||
translate([x_pos, 0, Height/2 + TotalThickness])
|
||||
cube([divider_thickness, InnerLength, Height], center=true);
|
||||
// Slots for horizontal dividers (top-down)
|
||||
for (j = [1 : Nb_Boxes_V - 1]) {
|
||||
y_pos = -InnerLength/2 + j * Compartment_V - divider_thickness/2;
|
||||
translate([x_pos, y_pos, Height * 0.75 + TotalThickness])
|
||||
cube([divider_thickness + 0.1, divider_thickness, Height/2], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Horizontal dividers (V-direction)
|
||||
for (j = [1 : Nb_Boxes_V - 1]) {
|
||||
y_pos = -InnerLength/2 + j * Compartment_V - divider_thickness/2;
|
||||
difference() {
|
||||
// Main divider piece
|
||||
translate([0, y_pos, Height/2 + TotalThickness])
|
||||
cube([InnerWidth, divider_thickness, Height], center=true);
|
||||
// Slots for vertical dividers (bottom-up)
|
||||
for (i = [1 : Nb_Boxes_U - 1]) {
|
||||
x_pos = -InnerWidth/2 + i * Compartment_U - divider_thickness/2;
|
||||
translate([x_pos, y_pos, Height * 0.25 + TotalThickness])
|
||||
cube([divider_thickness, divider_thickness + 0.1, Height/2], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Module for exporting all parts separately
|
||||
// ---------------------------------------------------------------------
|
||||
module export_layout() {
|
||||
wall_thickness = TotalThickness;
|
||||
InnerWidth = TotalWidth - 2 * Height;
|
||||
InnerLength = TotalLength - 2 * Height;
|
||||
|
||||
// 1. Base Plate
|
||||
translate([0, 0, -TotalThickness/2])
|
||||
cube([InnerWidth, InnerLength, wall_thickness], center = true);
|
||||
|
||||
// Spacing for laying out parts
|
||||
spacing = TotalWidth;
|
||||
|
||||
// 2. Outer Walls
|
||||
translate([spacing, 0, 0])
|
||||
cube([InnerWidth, Height, wall_thickness], center=true); // South
|
||||
translate([spacing, Height + 10, 0])
|
||||
cube([InnerWidth, Height, wall_thickness], center=true); // North
|
||||
|
||||
translate([spacing + InnerWidth + 10, 0, 0])
|
||||
cube([InnerLength - 2 * wall_thickness, Height, wall_thickness], center=true); // West
|
||||
translate([spacing + InnerWidth + 10, Height + 10, 0])
|
||||
cube([InnerLength - 2 * wall_thickness, Height, wall_thickness], center=true); // East
|
||||
|
||||
// 3. Internal Dividers
|
||||
divider_thickness = Slot_Width_Walls;
|
||||
Compartment_U = (InnerWidth + divider_thickness) / Nb_Boxes_U;
|
||||
Compartment_V = (InnerLength + divider_thickness) / Nb_Boxes_V;
|
||||
|
||||
// Place all vertical dividers in a row
|
||||
for (i = [1 : Nb_Boxes_U - 1]) {
|
||||
translate([2 * spacing + (i-1)*(divider_thickness+10), 0, 0])
|
||||
internal_divider_vertical_export(InnerLength, Compartment_V);
|
||||
}
|
||||
|
||||
// Place all horizontal dividers in a row
|
||||
for (j = [1 : Nb_Boxes_V - 1]) {
|
||||
translate([2 * spacing, (j-1)*(Height+10) + Height + 10, 0])
|
||||
internal_divider_horizontal_export(InnerWidth, Compartment_U);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper modules for export layout (without difference operations)
|
||||
module internal_divider_vertical_export(length, compartment_v_size) {
|
||||
divider_thickness = Slot_Width_Walls;
|
||||
difference() {
|
||||
cube([divider_thickness, length, Height], center=true);
|
||||
// Notches for horizontal dividers (bottom-up)
|
||||
for (i = [1 : Nb_Boxes_V - 1]) {
|
||||
y_pos = -length/2 + i * compartment_v_size - divider_thickness/2;
|
||||
translate([0, y_pos, -Height/4])
|
||||
cube([divider_thickness + 0.1, divider_thickness, Height/2], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module internal_divider_horizontal_export(length, compartment_u_size) {
|
||||
divider_thickness = Slot_Width_Walls;
|
||||
difference() {
|
||||
cube([length, divider_thickness, Height], center=true);
|
||||
// Notches for vertical dividers (top-down)
|
||||
for (j = [1 : Nb_Boxes_U - 1]) {
|
||||
x_pos = -length/2 + j * compartment_u_size - divider_thickness/2;
|
||||
translate([x_pos, 0, Height/4])
|
||||
cube([divider_thickness, divider_thickness + 0.1, Height/2], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Module to generate a markdown cut plan for the operator.
|
||||
// This version avoids all list manipulation for maximum compatibility.
|
||||
// ---------------------------------------------------------------------
|
||||
module generate_cut_plan_text() {
|
||||
// --- Calculations ---
|
||||
InnerWidth = TotalWidth - 2 * Height;
|
||||
InnerLength = TotalLength - 2 * Height;
|
||||
GrooveDepth = TotalThickness - BaseThickness;
|
||||
|
||||
// --- Markdown Output ---
|
||||
echo("# Saw Operator Cut Plan");
|
||||
echo(str("## Board Dimensions: `", TotalWidth, " x ", TotalLength, " mm`"));
|
||||
echo("");
|
||||
echo("## Specifications");
|
||||
echo(str("* **V-Groove Spec:** Depth `", GrooveDepth, " mm`"));
|
||||
echo(str("* **Slot Spec:** Width `", Slot_Width_Walls, " mm`, Depth `", GrooveDepth, " mm`"));
|
||||
echo("");
|
||||
echo("## Blade Setup");
|
||||
echo("* **For V-Grooves:** Set saw blade angle to **45 degrees**.");
|
||||
echo("* **For Slots:** Set saw blade angle to **0 degrees** (straight up).");
|
||||
echo("");
|
||||
|
||||
// --- Setup 1: Vertical Cuts ---
|
||||
echo("## SETUP 1: VERTICAL CUTS");
|
||||
echo("All distances are from the LEFT edge. Flip board for cuts > 50%.");
|
||||
echo("");
|
||||
echo(str("* `", Height, " mm` -- **V-GROOVE**"));
|
||||
if (Nb_Boxes_U > 1) {
|
||||
for (i = [1 : Nb_Boxes_U - 1]) {
|
||||
pos = Height + i * ((InnerWidth - (Nb_Boxes_U - 1) * Slot_Width_Walls) / Nb_Boxes_U) + i * Slot_Width_Walls;
|
||||
echo(str("* `", pos, " mm` -- **SLOT**"));
|
||||
}
|
||||
}
|
||||
echo(str("* `", TotalWidth - Height, " mm` -- **V-GROOVE**"));
|
||||
echo("");
|
||||
|
||||
// --- Setup 2: Horizontal Cuts ---
|
||||
echo("## SETUP 2: HORIZONTAL CUTS");
|
||||
echo("Rotate board 90 deg. All distances from the NEW LEFT edge.");
|
||||
echo("");
|
||||
echo(str("* `", Height, " mm` -- **V-GROOVE**"));
|
||||
if (Nb_Boxes_V > 1) {
|
||||
for (i = [1 : Nb_Boxes_V - 1]) {
|
||||
pos = Height + i * ((InnerLength - (Nb_Boxes_V - 1) * Slot_Width_Walls) / Nb_Boxes_V) + i * Slot_Width_Walls;
|
||||
echo(str("* `", pos, " mm` -- **SLOT**"));
|
||||
}
|
||||
}
|
||||
echo(str("* `", TotalLength - Height, " mm` -- **V-GROOVE**"));
|
||||
|
||||
echo("");
|
||||
echo("---");
|
||||
echo("*End of Plan*");
|
||||
|
||||
// Generate a tiny invisible cube because OpenSCAD needs to produce some geometry.
|
||||
cube(0.01);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Render the final object
|
||||
// ---------------------------------------------------------------------
|
||||
if (view_mode == "export") {
|
||||
export_layout();
|
||||
} else if (view_mode == "dxf") {
|
||||
// Project the 2D unfolded pattern for DXF export
|
||||
projection(cut = true) unfolded_pattern();
|
||||
} else if (view_mode == "cutplan") {
|
||||
generate_cut_plan_text();
|
||||
} else {
|
||||
if (Folded_View) {
|
||||
folded_box();
|
||||
} else {
|
||||
unfolded_pattern();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
BIN
products/poly-mech/cad/joints/corner-joints/LJoint-Test.STEP
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/corner-joints/LJoint-Test.STEP
(Stored with Git LFS)
Binary file not shown.
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 96 KiB |
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/2024_WasherM6_x4_1mm_INOX.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/2024_WasherM6_x4_1mm_INOX.SLDPRT
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/204060R_Cover_x2_1mm_INOX.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/204060R_Cover_x2_1mm_INOX.SLDPRT
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/2040_Shield_x2_1mm_INOX.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/2040_Shield_x2_1mm_INOX.SLDPRT
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/Fasteners.SLDASM
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/Fasteners.SLDASM
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/Fasteners.jpg
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/Fasteners.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/Fasteners.pdf
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/Fasteners.pdf
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/Fasteners.x_t
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/Fasteners.x_t
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/M6-50.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/M6-50.SLDPRT
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/M6Nut.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/M6Nut.SLDPRT
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/SlideDual-20ID-40D-60W.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/SlideDual-20ID-40D-60W.SLDPRT
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/SlideSingle-20ID-40H-60W.SLDASM
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/SlideSingle-20ID-40H-60W.SLDASM
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/SlideSingle-20ID-40H-60W.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/SlideSingle-20ID-40H-60W.SLDPRT
(Stored with Git LFS)
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/SlideSingle-20ID-40H-60W.jpg
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/SlideSingle-20ID-40H-60W.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/SlideSingle-20ID-40H-60W.pdf
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/SlideSingle-20ID-40H-60W.pdf
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/SlideSingle-20ID-40H-60W.step
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/SlideSingle-20ID-40H-60W.step
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/SlideSingle-20ID-40H-60W.x_t
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/SlideSingle-20ID-40H-60W.x_t
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/lbbr25-skf.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/side-clamp-20ID-60-40/lbbr25-skf.SLDPRT
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/20-40-100_WasherM6_x4_1mm_INOX.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/20-40-100_WasherM6_x4_1mm_INOX.SLDPRT
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/20-50-100_Shield_x2_1mm_INOX.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/20-50-100_Shield_x2_1mm_INOX.SLDPRT
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/2040_Shield_x2_1mm_INOX.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/2040_Shield_x2_1mm_INOX.SLDPRT
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/Cover.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/Cover.SLDPRT
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/Fasteners-M6.SLDASM
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/Fasteners-M6.SLDASM
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/Fasteners.x_t
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/Fasteners.x_t
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/M6-50.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/M6-50.SLDPRT
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/M6-Washers.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/M6-Washers.SLDPRT
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/M6Nut.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/M6Nut.SLDPRT
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/SlideDual-20ID-50D-100W.SLDPRT
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/SlideDual-20ID-50D-100W.SLDPRT
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/SlideDual-20ID-50H-100W-Nema23.SLDASM
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/SlideDual-20ID-50H-100W-Nema23.SLDASM
(Stored with Git LFS)
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/SlideDual-20ID-50H-100W-Nema23.jpg
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/SlideDual-20ID-50H-100W-Nema23.jpg
(Stored with Git LFS)
Binary file not shown.
@ -1,42 +0,0 @@
|
||||
[
|
||||
{
|
||||
"File Path": "C:\\Users\\mc007\\Desktop\\osr\\products\\products\\products\\poly-mech\\cad\\joints\\slide-clamp-20ID-100-50\\SlideDual-20ID-50H-100W-Nema23.SLDASM"
|
||||
},
|
||||
{
|
||||
"File Path": "C:\\Users\\mc007\\Desktop\\osr\\products\\products\\components\\servos\\nema23\\default\\cad\\Body_nema23_23HS30-2804S.SLDPRT"
|
||||
},
|
||||
{
|
||||
"File Path": "c:\\solidworks data (2)\\browser\\iso\\bolts and screws\\cross-recessed head screws\\pan head cross recess screw_iso.sldprt"
|
||||
},
|
||||
{
|
||||
"File Path": "C:\\Users\\mc007\\Desktop\\osr\\products\\products\\components\\servos\\nema23\\default\\cad\\Nema23.SLDASM"
|
||||
},
|
||||
{
|
||||
"File Path": "C:\\Users\\mc007\\Desktop\\osr\\products\\products\\products\\poly-mech\\cad\\joints\\slide-clamp-20ID-100-50\\SlideDual-20ID-50D-100W.SLDPRT",
|
||||
"Total Bounding Box Length": "100",
|
||||
"Total Bounding Box Width": "50",
|
||||
"Total Bounding Box Thickness": "50",
|
||||
"Total Bounding Box Volume": "250000"
|
||||
},
|
||||
{
|
||||
"File Path": "c:\\solidworks data (2)\\browser\\ansi metric\\bolts and screws\\hex head\\formed hex screw_am.sldprt"
|
||||
},
|
||||
{
|
||||
"File Path": "c:\\solidworks data (2)\\browser\\ansi metric\\nuts\\hex nuts\\hex nut jam_am.sldprt"
|
||||
},
|
||||
{
|
||||
"File Path": "C:\\Users\\mc007\\Desktop\\osr\\products\\products\\products\\poly-mech\\cad\\joints\\slide-clamp-20ID-100-50\\Fasteners-M6.SLDASM"
|
||||
},
|
||||
{
|
||||
"File Path": "C:\\Users\\mc007\\Desktop\\osr\\products\\products\\products\\poly-mech\\cad\\joints\\slide-clamp-20ID-100-50\\20-50-100_Shield_x2_1mm_INOX.SLDPRT"
|
||||
},
|
||||
{
|
||||
"File Path": "C:\\Users\\mc007\\Desktop\\osr\\products\\products\\products\\poly-mech\\cad\\joints\\slide-clamp-20ID-100-50\\20-40-100_WasherM6_x4_1mm_INOX.SLDPRT"
|
||||
},
|
||||
{
|
||||
"File Path": "C:\\Users\\mc007\\Desktop\\osr\\products\\products\\products\\poly-mech\\cad\\joints\\slide-clamp-20ID-100-50\\SlideDual-20ID-50H-100W.SLDASM"
|
||||
},
|
||||
{
|
||||
"File Path": "C:\\Users\\mc007\\Desktop\\osr\\products\\products\\components\\servos\\nema17\\default\\cad_en\\nema17-stepper-motor-9.snapshot.1\\Nema17-Default.SLDPRT"
|
||||
}
|
||||
]
|
||||
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/SlideDual-20ID-50H-100W-Nema23.step
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/SlideDual-20ID-50H-100W-Nema23.step
(Stored with Git LFS)
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/SlideDual-20ID-50H-100W-Nema23.x_t
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/SlideDual-20ID-50H-100W-Nema23.x_t
(Stored with Git LFS)
Binary file not shown.
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/SlideDual-20ID-50H-100W.SLDASM
(Stored with Git LFS)
BIN
products/poly-mech/cad/joints/slide-clamp-20ID-100-50/SlideDual-20ID-50H-100W.SLDASM
(Stored with Git LFS)
Binary file not shown.
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user