Merge branch 'master' into master
This commit is contained in:
2
.github/ISSUE_TEMPLATE/modelling-question.md
vendored
2
.github/ISSUE_TEMPLATE/modelling-question.md
vendored
@ -18,7 +18,7 @@ are appreciated.
|
|||||||
If you want to discuss something in a more casual environment, we have other options under [Getting help in the README.md](https://github.com/CadQuery/cadquery#getting-help). There are also additional examples in the [cadquery-contrib repository](https://github.com/CadQuery/cadquery-contrib).
|
If you want to discuss something in a more casual environment, we have other options under [Getting help in the README.md](https://github.com/CadQuery/cadquery#getting-help). There are also additional examples in the [cadquery-contrib repository](https://github.com/CadQuery/cadquery-contrib).
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- We are all volunteers here, you can help us help you by making this question quick to answer. Minimal examples, trimmed of all unreleated code are appreciated. It also helps if you provide code that can be cut and pasted into CQ-Editor. ie. instead of:
|
<!-- We are all volunteers here, you can help us help you by making this question quick to answer. Minimal examples, trimmed of all unrelated code are appreciated. It also helps if you provide code that can be cut and pasted into CQ-Editor. ie. instead of:
|
||||||
|
|
||||||
> I have a box, how to I fillet a top corner?
|
> I have a box, how to I fillet a top corner?
|
||||||
|
|
||||||
|
10
.gitignore
vendored
10
.gitignore
vendored
@ -9,3 +9,13 @@ target/*
|
|||||||
MANIFEST
|
MANIFEST
|
||||||
out.*
|
out.*
|
||||||
res?.dxf
|
res?.dxf
|
||||||
|
.~*
|
||||||
|
assy.wrl
|
||||||
|
assy.xml
|
||||||
|
assy.zip
|
||||||
|
nested.step
|
||||||
|
simple.caf
|
||||||
|
simple.step
|
||||||
|
simple.stp
|
||||||
|
simple.xml
|
||||||
|
test.brep
|
||||||
|
@ -15,8 +15,8 @@ CadQuery is an intuitive, easy-to-use Python module for building parametric 3D C
|
|||||||
CadQuery is often compared to [OpenSCAD](http://www.openscad.org/). Like OpenSCAD, CadQuery is an open-source, script based, parametric model generator. However, CadQuery stands out in many ways and has several key advantages:
|
CadQuery is often compared to [OpenSCAD](http://www.openscad.org/). Like OpenSCAD, CadQuery is an open-source, script based, parametric model generator. However, CadQuery stands out in many ways and has several key advantages:
|
||||||
|
|
||||||
1. The scripts use a standard programming language, Python, and thus can benefit from the associated infrastructure. This includes many standard libraries and IDEs.
|
1. The scripts use a standard programming language, Python, and thus can benefit from the associated infrastructure. This includes many standard libraries and IDEs.
|
||||||
2. CadQuery's CAD kernel Open CASCADE Technology (OCCT) is much more powerful than CGAL. Features supported natively by OCCT include NURBS, splines, surface sewing, STL repair, STEP import/export, and other complex operations, in addition to the standard CSG operations supported by CGAL
|
2. CadQuery's CAD kernel Open CASCADE Technology ([OCCT](https://en.wikipedia.org/wiki/Open_Cascade_Technology)) is much more powerful than the [CGAL](https://en.wikipedia.org/wiki/CGAL) used by OpenSCAD. Features supported natively by OCCT include NURBS, splines, surface sewing, STL repair, STEP import/export, and other complex operations, in addition to the standard CSG operations supported by CGAL
|
||||||
3. Ability to import/export STEP and the ability to begin with a STEP model, created in a CAD package, and then add parametric features. This is possible in OpenSCAD using STL, but STL is a lossy format.
|
3. Ability to import/export [STEP](https://en.wikipedia.org/wiki/ISO_10303) and the ability to begin with a STEP model, created in a CAD package, and then add parametric features. This is possible in OpenSCAD using STL, but STL is a lossy format.
|
||||||
4. CadQuery scripts require less code to create most objects, because it is possible to locate features based on the position of other features, workplanes, vertices, etc.
|
4. CadQuery scripts require less code to create most objects, because it is possible to locate features based on the position of other features, workplanes, vertices, etc.
|
||||||
5. CadQuery scripts can build STL, STEP, and AMF faster than OpenSCAD.
|
5. CadQuery scripts can build STL, STEP, and AMF faster than OpenSCAD.
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ CadQuery is often compared to [OpenSCAD](http://www.openscad.org/). Like OpenSCA
|
|||||||
* Create parametric models that can be very easily customized by end users.
|
* Create parametric models that can be very easily customized by end users.
|
||||||
* Output high quality (loss-less) CAD formats like STEP and DXF in addition to STL, VRML and AMF.
|
* Output high quality (loss-less) CAD formats like STEP and DXF in addition to STL, VRML and AMF.
|
||||||
* Provide a non-proprietary, plain text model format that can be edited and executed with only a web browser.
|
* Provide a non-proprietary, plain text model format that can be edited and executed with only a web browser.
|
||||||
* Offer advanced modeling capabilities such as fillets, curvelinear extrudes, parametric curves and lofts.
|
* Offer advanced modeling capabilities such as fillets, curvilinear extrudes, parametric curves and lofts.
|
||||||
* Build nested assemblies out of individual parts and other assemblies.
|
* Build nested assemblies out of individual parts and other assemblies.
|
||||||
|
|
||||||
### Why this fork
|
### Why this fork
|
||||||
@ -175,7 +175,7 @@ If you are going to contribute code, make sure to follow this steps:
|
|||||||
start working on your changes
|
start working on your changes
|
||||||
- Create a conda development environment with something like:
|
- Create a conda development environment with something like:
|
||||||
- `conda env create -n cq-dev -f environment.yml`
|
- `conda env create -n cq-dev -f environment.yml`
|
||||||
- Activate the new conda enviornment:
|
- Activate the new conda environment:
|
||||||
- `conda activate cq-dev`
|
- `conda activate cq-dev`
|
||||||
- If desired, install the master branch of cq-editor (Note; a release version may not be compatible with the master branch of cadquery):
|
- If desired, install the master branch of cq-editor (Note; a release version may not be compatible with the master branch of cadquery):
|
||||||
- `conda install -c cadquery -c conda-forge cq-editor=master`
|
- `conda install -c cadquery -c conda-forge cq-editor=master`
|
||||||
|
@ -26,7 +26,7 @@ ExportLiterals = Literal["STEP", "XML"]
|
|||||||
|
|
||||||
PATH_DELIM = "/"
|
PATH_DELIM = "/"
|
||||||
|
|
||||||
# enitity selector grammar definiiton
|
# entity selector grammar definiiton
|
||||||
def _define_grammar():
|
def _define_grammar():
|
||||||
|
|
||||||
from pyparsing import (
|
from pyparsing import (
|
||||||
@ -83,11 +83,11 @@ class Constraint(object):
|
|||||||
"""
|
"""
|
||||||
Construct a constraint.
|
Construct a constraint.
|
||||||
|
|
||||||
:param objects: object names refernced in the constraint
|
:param objects: object names referenced in the constraint
|
||||||
:param args: subshapes (e.g. faces or edges) of the objects
|
:param args: subshapes (e.g. faces or edges) of the objects
|
||||||
:param sublocs: locations of the objects (only relevant if the objects are nested in a sub-assembly)
|
:param sublocs: locations of the objects (only relevant if the objects are nested in a sub-assembly)
|
||||||
:param kind: constraint kind
|
:param kind: constraint kind
|
||||||
:param param: optional arbitrary paramter passed to the solver
|
:param param: optional arbitrary parameter passed to the solver
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.objects = objects
|
self.objects = objects
|
||||||
@ -357,7 +357,7 @@ class Assembly(object):
|
|||||||
"""
|
"""
|
||||||
Calculate relative location of an object in a subassembly.
|
Calculate relative location of an object in a subassembly.
|
||||||
|
|
||||||
Returns the relative posiitons as well as the name of the top assembly.
|
Returns the relative positions as well as the name of the top assembly.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
rv = Location()
|
rv = Location()
|
||||||
@ -411,7 +411,7 @@ class Assembly(object):
|
|||||||
elif len(args) == 6:
|
elif len(args) == 6:
|
||||||
id1, s1, id2, s2, kind, param = args
|
id1, s1, id2, s2, kind, param = args
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Incompatibile arguments: {args}")
|
raise ValueError(f"Incompatible arguments: {args}")
|
||||||
|
|
||||||
loc1, id1_top = self._subloc(id1)
|
loc1, id1_top = self._subloc(id1)
|
||||||
loc2, id2_top = self._subloc(id2)
|
loc2, id2_top = self._subloc(id2)
|
||||||
|
113
cadquery/cq.py
113
cadquery/cq.py
@ -130,7 +130,7 @@ class CQContext(object):
|
|||||||
|
|
||||||
class Workplane(object):
|
class Workplane(object):
|
||||||
"""
|
"""
|
||||||
Defines a coordinate system in space, in which 2-d coordinates can be used.
|
Defines a coordinate system in space, in which 2D coordinates can be used.
|
||||||
|
|
||||||
:param plane: the plane in which the workplane will be done
|
:param plane: the plane in which the workplane will be done
|
||||||
:type plane: a Plane object, or a string in (XY|YZ|XZ|front|back|top|bottom|left|right)
|
:type plane: a Plane object, or a string in (XY|YZ|XZ|front|back|top|bottom|left|right)
|
||||||
@ -305,7 +305,7 @@ class Workplane(object):
|
|||||||
)
|
)
|
||||||
rv = [solid.split(*tools)]
|
rv = [solid.split(*tools)]
|
||||||
|
|
||||||
# split using the current wokrplane
|
# split using the current workplane
|
||||||
else:
|
else:
|
||||||
|
|
||||||
# boilerplate for arg/kwarg parsing
|
# boilerplate for arg/kwarg parsing
|
||||||
@ -501,7 +501,7 @@ class Workplane(object):
|
|||||||
origin: Optional[VectorLike] = None,
|
origin: Optional[VectorLike] = None,
|
||||||
) -> T:
|
) -> T:
|
||||||
"""
|
"""
|
||||||
Creates a new 2-D workplane, located relative to the first face on the stack.
|
Creates a new 2D workplane, located relative to the first face on the stack.
|
||||||
|
|
||||||
:param offset: offset for the work plane in the Z direction. Default
|
:param offset: offset for the work plane in the Z direction. Default
|
||||||
:param invert: invert the Z direction from that of the face.
|
:param invert: invert the Z direction from that of the face.
|
||||||
@ -518,7 +518,7 @@ class Workplane(object):
|
|||||||
item on the chain immediately before the vertex must be a
|
item on the chain immediately before the vertex must be a
|
||||||
face.
|
face.
|
||||||
|
|
||||||
The result will be a 2-d working plane
|
The result will be a 2D working plane
|
||||||
with a new coordinate system set up as follows:
|
with a new coordinate system set up as follows:
|
||||||
|
|
||||||
* The centerOption parameter sets how the center is defined.
|
* The centerOption parameter sets how the center is defined.
|
||||||
@ -1087,7 +1087,7 @@ class Workplane(object):
|
|||||||
Future Enhancements:
|
Future Enhancements:
|
||||||
* A version of this method that returns a transformed copy, rather than modifying
|
* A version of this method that returns a transformed copy, rather than modifying
|
||||||
the originals
|
the originals
|
||||||
* This method doesnt expose a very good interface, because the axis of rotation
|
* This method doesn't expose a very good interface, because the axis of rotation
|
||||||
could be inconsistent between multiple objects. This is because the beginning
|
could be inconsistent between multiple objects. This is because the beginning
|
||||||
of the axis is variable, while the end is fixed. This is fine when operating on
|
of the axis is variable, while the end is fixed. This is fine when operating on
|
||||||
one object, but is not cool for multiple.
|
one object, but is not cool for multiple.
|
||||||
@ -1212,7 +1212,7 @@ class Workplane(object):
|
|||||||
|
|
||||||
:param thickness: a positive float, representing the thickness of the desired shell.
|
:param thickness: a positive float, representing the thickness of the desired shell.
|
||||||
Negative values shell inwards, positive values shell outwards.
|
Negative values shell inwards, positive values shell outwards.
|
||||||
:param kind: kind of joints, intersetion or arc (default: arc).
|
:param kind: kind of joints, intersection or arc (default: arc).
|
||||||
:raises ValueError: if the current stack contains objects that are not faces of a solid
|
:raises ValueError: if the current stack contains objects that are not faces of a solid
|
||||||
further up in the chain.
|
further up in the chain.
|
||||||
:returns: a CQ object with the resulting shelled solid selected.
|
:returns: a CQ object with the resulting shelled solid selected.
|
||||||
@ -1531,7 +1531,7 @@ class Workplane(object):
|
|||||||
def pushPoints(self: T, pntList: Iterable[Union[VectorLike, Location]]) -> T:
|
def pushPoints(self: T, pntList: Iterable[Union[VectorLike, Location]]) -> T:
|
||||||
"""
|
"""
|
||||||
Pushes a list of points onto the stack as vertices.
|
Pushes a list of points onto the stack as vertices.
|
||||||
The points are in the 2-d coordinate space of the workplane face
|
The points are in the 2D coordinate space of the workplane face
|
||||||
|
|
||||||
:param pntList: a list of points to push onto the stack
|
:param pntList: a list of points to push onto the stack
|
||||||
:type pntList: list of 2-tuples, in *local* coordinates
|
:type pntList: list of 2-tuples, in *local* coordinates
|
||||||
@ -1687,7 +1687,7 @@ class Workplane(object):
|
|||||||
self: T, distance: float, angle: float, forConstruction: bool = False
|
self: T, distance: float, angle: float, forConstruction: bool = False
|
||||||
) -> T:
|
) -> T:
|
||||||
"""
|
"""
|
||||||
Make a line from the current point to the given polar co-ordinates
|
Make a line from the current point to the given polar coordinates
|
||||||
|
|
||||||
Useful if it is more convenient to specify the end location rather than
|
Useful if it is more convenient to specify the end location rather than
|
||||||
the distance and angle from the current point
|
the distance and angle from the current point
|
||||||
@ -1817,11 +1817,11 @@ class Workplane(object):
|
|||||||
where a tangent constraint is specified.
|
where a tangent constraint is specified.
|
||||||
:param periodic: creation of periodic curves
|
:param periodic: creation of periodic curves
|
||||||
:param parameters: the value of the parameter at each interpolation point.
|
:param parameters: the value of the parameter at each interpolation point.
|
||||||
(The intepolated curve is represented as a vector-valued function of a
|
(The interpolated curve is represented as a vector-valued function of a
|
||||||
scalar parameter.)
|
scalar parameter.)
|
||||||
|
|
||||||
If periodic == True, then len(parameters) must be
|
If periodic == True, then len(parameters) must be
|
||||||
len(intepolation points) + 1, otherwise len(parameters) must be equal to
|
len(interpolation points) + 1, otherwise len(parameters) must be equal to
|
||||||
len(interpolation points).
|
len(interpolation points).
|
||||||
:param scale: whether to scale the specified tangent vectors before
|
:param scale: whether to scale the specified tangent vectors before
|
||||||
interpolating.
|
interpolating.
|
||||||
@ -2356,11 +2356,11 @@ class Workplane(object):
|
|||||||
:param forConstruction: whether the wire should be used to make a solid, or if it is just
|
:param forConstruction: whether the wire should be used to make a solid, or if it is just
|
||||||
for reference
|
for reference
|
||||||
|
|
||||||
This method is primarily of use to plugin developers making utilities for 2-d construction.
|
This method is primarily of use to plugin developers making utilities for 2D construction.
|
||||||
This method should be called when a user operation implies that 2-d construction is
|
This method should be called when a user operation implies that 2D construction is
|
||||||
finished, and we are ready to begin working in 3d.
|
finished, and we are ready to begin working in 3d.
|
||||||
|
|
||||||
SEE '2-d construction concepts' for a more detailed explanation of how CadQuery handles
|
SEE '2D construction concepts' for a more detailed explanation of how CadQuery handles
|
||||||
edges, wires, etc.
|
edges, wires, etc.
|
||||||
|
|
||||||
Any non edges will still remain.
|
Any non edges will still remain.
|
||||||
@ -2693,11 +2693,11 @@ class Workplane(object):
|
|||||||
|
|
||||||
def close(self: T) -> T:
|
def close(self: T) -> T:
|
||||||
"""
|
"""
|
||||||
End 2-d construction, and attempt to build a closed wire.
|
End 2D construction, and attempt to build a closed wire.
|
||||||
|
|
||||||
:return: a CQ object with a completed wire on the stack, if possible.
|
:return: a CQ object with a completed wire on the stack, if possible.
|
||||||
|
|
||||||
After 2-d drafting with methods such as lineTo, threePointArc,
|
After 2D drafting with methods such as lineTo, threePointArc,
|
||||||
tangentArcPoint and polyline, it is necessary to convert the edges
|
tangentArcPoint and polyline, it is necessary to convert the edges
|
||||||
produced by these into one or more wires.
|
produced by these into one or more wires.
|
||||||
|
|
||||||
@ -2710,7 +2710,7 @@ class Workplane(object):
|
|||||||
endPoint = self._findFromPoint(True)
|
endPoint = self._findFromPoint(True)
|
||||||
|
|
||||||
if self.ctx.firstPoint is None:
|
if self.ctx.firstPoint is None:
|
||||||
raise ValueError("Not start point specified - cannot close")
|
raise ValueError("No start point specified - cannot close")
|
||||||
else:
|
else:
|
||||||
startPoint = self.ctx.firstPoint
|
startPoint = self.ctx.firstPoint
|
||||||
|
|
||||||
@ -2767,7 +2767,7 @@ class Workplane(object):
|
|||||||
|
|
||||||
return self.newObject([s])
|
return self.newObject([s])
|
||||||
|
|
||||||
# but parameter list is different so a simple function pointer wont work
|
# but parameter list is different so a simple function pointer won't work
|
||||||
def cboreHole(
|
def cboreHole(
|
||||||
self: T,
|
self: T,
|
||||||
diameter: float,
|
diameter: float,
|
||||||
@ -2813,7 +2813,7 @@ class Workplane(object):
|
|||||||
# first make the hole
|
# first make the hole
|
||||||
hole = Solid.makeCylinder(
|
hole = Solid.makeCylinder(
|
||||||
diameter / 2.0, depth, center, boreDir
|
diameter / 2.0, depth, center, boreDir
|
||||||
) # local coordianates!
|
) # local coordinates!
|
||||||
|
|
||||||
# add the counter bore
|
# add the counter bore
|
||||||
cbore = Solid.makeCylinder(cboreDiameter / 2.0, cboreDepth, Vector(), boreDir)
|
cbore = Solid.makeCylinder(cboreDiameter / 2.0, cboreDepth, Vector(), boreDir)
|
||||||
@ -2822,7 +2822,7 @@ class Workplane(object):
|
|||||||
return self.cutEach(lambda loc: r.moved(loc), True, clean)
|
return self.cutEach(lambda loc: r.moved(loc), True, clean)
|
||||||
|
|
||||||
# TODO: almost all code duplicated!
|
# TODO: almost all code duplicated!
|
||||||
# but parameter list is different so a simple function pointer wont work
|
# but parameter list is different so a simple function pointer won't work
|
||||||
def cskHole(
|
def cskHole(
|
||||||
self: T,
|
self: T,
|
||||||
diameter: float,
|
diameter: float,
|
||||||
@ -2879,7 +2879,7 @@ class Workplane(object):
|
|||||||
return self.cutEach(lambda loc: res.moved(loc), True, clean)
|
return self.cutEach(lambda loc: res.moved(loc), True, clean)
|
||||||
|
|
||||||
# TODO: almost all code duplicated!
|
# TODO: almost all code duplicated!
|
||||||
# but parameter list is different so a simple function pointer wont work
|
# but parameter list is different so a simple function pointer won't work
|
||||||
def hole(
|
def hole(
|
||||||
self: T, diameter: float, depth: Optional[float] = None, clean: bool = True,
|
self: T, diameter: float, depth: Optional[float] = None, clean: bool = True,
|
||||||
) -> T:
|
) -> T:
|
||||||
@ -3463,7 +3463,7 @@ class Workplane(object):
|
|||||||
eDir = self.plane.zDir.multiply(distance)
|
eDir = self.plane.zDir.multiply(distance)
|
||||||
|
|
||||||
# one would think that fusing faces into a compound and then extruding would work,
|
# one would think that fusing faces into a compound and then extruding would work,
|
||||||
# but it doesnt-- the resulting compound appears to look right, ( right number of faces, etc)
|
# but it doesn't-- the resulting compound appears to look right, ( right number of faces, etc)
|
||||||
# but then cutting it from the main solid fails with BRep_NotDone.
|
# but then cutting it from the main solid fails with BRep_NotDone.
|
||||||
# the work around is to extrude each and then join the resulting solids, which seems to work
|
# the work around is to extrude each and then join the resulting solids, which seems to work
|
||||||
|
|
||||||
@ -3589,7 +3589,7 @@ class Workplane(object):
|
|||||||
maxSegments: int = 9,
|
maxSegments: int = 9,
|
||||||
) -> T:
|
) -> T:
|
||||||
"""
|
"""
|
||||||
Returns a plate surface that is 'thickness' thick, enclosed by 'surf_edge_pts' points, and going through 'surf_pts' points. Using pushpoints directly with interpPlate and combine=True, can be very ressources intensive depending on the complexity of the shape. In this case set combine=False.
|
Returns a plate surface that is 'thickness' thick, enclosed by 'surf_edge_pts' points, and going through 'surf_pts' points. Using pushpoints directly with interpPlate and combine=True, can be very resources intensive depending on the complexity of the shape. In this case set combine=False.
|
||||||
|
|
||||||
:param surf_edges
|
:param surf_edges
|
||||||
:type 1 surf_edges: list of [x,y,z] float ordered coordinates
|
:type 1 surf_edges: list of [x,y,z] float ordered coordinates
|
||||||
@ -3597,7 +3597,7 @@ class Workplane(object):
|
|||||||
:param surf_pts = [] (uses only edges if [])
|
:param surf_pts = [] (uses only edges if [])
|
||||||
:type surf_pts: list of [x,y,z] float coordinates
|
:type surf_pts: list of [x,y,z] float coordinates
|
||||||
:param thickness = 0 (returns 2D surface if 0)
|
:param thickness = 0 (returns 2D surface if 0)
|
||||||
:type thickness: float (may be negative or positive depending on thicknening direction)
|
:type thickness: float (may be negative or positive depending on thickening direction)
|
||||||
:param combine: should the results be combined with other solids on the stack
|
:param combine: should the results be combined with other solids on the stack
|
||||||
(and each other)?
|
(and each other)?
|
||||||
:type combine: true to combine shapes, false otherwise.
|
:type combine: true to combine shapes, false otherwise.
|
||||||
@ -3608,8 +3608,8 @@ class Workplane(object):
|
|||||||
:type: NbPtsOnCur Integer >= 15
|
:type: NbPtsOnCur Integer >= 15
|
||||||
:param NbIter = 2 (OCCT default)
|
:param NbIter = 2 (OCCT default)
|
||||||
:type: NbIterInteger >= 2
|
:type: NbIterInteger >= 2
|
||||||
:param Anisotropie = False (OCCT default)
|
:param anisotropy = False (OCCT default)
|
||||||
:type Anisotropie: Boolean
|
:type anisotropy: Boolean
|
||||||
:param: Tol2d = 0.00001 (OCCT default)
|
:param: Tol2d = 0.00001 (OCCT default)
|
||||||
:type Tol2d: float > 0
|
:type Tol2d: float > 0
|
||||||
:param Tol3d = 0.0001 (OCCT default)
|
:param Tol3d = 0.0001 (OCCT default)
|
||||||
@ -3800,6 +3800,69 @@ class Workplane(object):
|
|||||||
else:
|
else:
|
||||||
return self.union(spheres, clean=clean)
|
return self.union(spheres, clean=clean)
|
||||||
|
|
||||||
|
def cylinder(
|
||||||
|
self: T,
|
||||||
|
height: float,
|
||||||
|
radius: float,
|
||||||
|
direct: Vector = Vector(0, 0, 1),
|
||||||
|
angle: float = 360,
|
||||||
|
centered: Union[bool, Tuple[bool, bool, bool]] = True,
|
||||||
|
combine: bool = True,
|
||||||
|
clean: bool = True,
|
||||||
|
) -> T:
|
||||||
|
"""
|
||||||
|
Returns a cylinder with the specified radius and height for each point on the stack
|
||||||
|
|
||||||
|
:param height: The height of the cylinder
|
||||||
|
:type height: float > 0
|
||||||
|
:param radius: The radius of the cylinder
|
||||||
|
:type radius: float > 0
|
||||||
|
:param direct: The direction axis for the creation of the cylinder
|
||||||
|
:type direct: A three-tuple
|
||||||
|
:param angle: The angle to sweep the cylinder arc through
|
||||||
|
:type angle: float > 0
|
||||||
|
:param centered: If True, the cylinder will be centered around the reference point. If False,
|
||||||
|
the corner of a bounding box around the cylinder will be on the reference point and it
|
||||||
|
will extend in the positive x, y and z directions. Can also use a 3-tuple to specify
|
||||||
|
centering along each axis.
|
||||||
|
:param combine: Whether the results should be combined with other solids on the stack
|
||||||
|
(and each other)
|
||||||
|
:type combine: true to combine shapes, false otherwise
|
||||||
|
:param clean: call :py:meth:`clean` afterwards to have a clean shape
|
||||||
|
:return: A cylinder object for each point on the stack
|
||||||
|
|
||||||
|
One cylinder is created for each item on the current stack. If no items are on the stack, one
|
||||||
|
cylinder is created using the current workplane center.
|
||||||
|
|
||||||
|
If combine is true, the result will be a single object on the stack. If a solid was found
|
||||||
|
in the chain, the result is that solid with all cylinders produced fused onto it otherwise,
|
||||||
|
the result is the combination of all the produced cylinders.
|
||||||
|
|
||||||
|
If combine is false, the result will be a list of the cylinders produced.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if isinstance(centered, bool):
|
||||||
|
centered = (centered, centered, centered)
|
||||||
|
|
||||||
|
offset = Vector()
|
||||||
|
if not centered[0]:
|
||||||
|
offset += Vector(radius, 0, 0)
|
||||||
|
if not centered[1]:
|
||||||
|
offset += Vector(0, radius, 0)
|
||||||
|
if centered[2]:
|
||||||
|
offset += Vector(0, 0, -height / 2)
|
||||||
|
|
||||||
|
s = Solid.makeCylinder(radius, height, offset, direct, angle)
|
||||||
|
|
||||||
|
# We want a cylinder for each point on the workplane
|
||||||
|
cylinders = self.eachpoint(lambda loc: s.moved(loc), True)
|
||||||
|
|
||||||
|
# If we don't need to combine everything, just return the created cylinders
|
||||||
|
if not combine:
|
||||||
|
return cylinders
|
||||||
|
else:
|
||||||
|
return self.union(cylinders, clean=clean)
|
||||||
|
|
||||||
def wedge(
|
def wedge(
|
||||||
self: T,
|
self: T,
|
||||||
dx: float,
|
dx: float,
|
||||||
|
@ -153,7 +153,7 @@ class ShapeResult(object):
|
|||||||
class BuildResult(object):
|
class BuildResult(object):
|
||||||
"""
|
"""
|
||||||
The result of executing a CadQuery script.
|
The result of executing a CadQuery script.
|
||||||
The success property contains whether the exeuction was successful.
|
The success property contains whether the execution was successful.
|
||||||
|
|
||||||
If successful, the results property contains a list of all results,
|
If successful, the results property contains a list of all results,
|
||||||
and the first_result property contains the first result.
|
and the first_result property contains the first result.
|
||||||
|
@ -76,15 +76,22 @@ def _dxf_spline(e: Edge, msp: ezdxf.layouts.Modelspace, plane: Plane):
|
|||||||
curve, adaptor.FirstParameter(), adaptor.LastParameter(), CURVE_TOLERANCE
|
curve, adaptor.FirstParameter(), adaptor.LastParameter(), CURVE_TOLERANCE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# need to apply the transform on the geometry level
|
||||||
|
spline.Transform(plane.fG.wrapped.Trsf())
|
||||||
|
|
||||||
order = spline.Degree() + 1
|
order = spline.Degree() + 1
|
||||||
knots = list(spline.KnotSequence())
|
knots = list(spline.KnotSequence())
|
||||||
poles = [(p.X(), p.Y(), p.Z()) for p in spline.Poles()]
|
poles = [(p.X(), p.Y(), p.Z()) for p in spline.Poles()]
|
||||||
|
weights = (
|
||||||
|
[spline.Weight(i) for i in range(1, spline.NbPoles() + 1)]
|
||||||
|
if spline.IsRational()
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
|
||||||
weights = list(spline.Weights()) if spline.IsRational() else None
|
if spline.IsPeriodic():
|
||||||
|
pad = spline.NbKnots() - spline.LastUKnotIndex()
|
||||||
|
poles += poles[:pad]
|
||||||
|
|
||||||
if spline.IsClosed():
|
|
||||||
dxf_spline = ezdxf.math.BSplineClosed(poles, order, knots, weights)
|
|
||||||
else:
|
|
||||||
dxf_spline = ezdxf.math.BSpline(poles, order, knots, weights)
|
dxf_spline = ezdxf.math.BSpline(poles, order, knots, weights)
|
||||||
|
|
||||||
msp.add_spline().apply_construction_tool(dxf_spline)
|
msp.add_spline().apply_construction_tool(dxf_spline)
|
||||||
|
@ -223,7 +223,7 @@ def getSVG(shape, opts=None):
|
|||||||
hidden = list(map(Shape, hidden))
|
hidden = list(map(Shape, hidden))
|
||||||
(hiddenPaths, visiblePaths) = getPaths(visible, hidden)
|
(hiddenPaths, visiblePaths) = getPaths(visible, hidden)
|
||||||
|
|
||||||
# get bounding box -- these are all in 2-d space
|
# get bounding box -- these are all in 2D space
|
||||||
bb = Compound.makeCompound(hidden + visible).BoundingBox()
|
bb = Compound.makeCompound(hidden + visible).BoundingBox()
|
||||||
|
|
||||||
# width pixels for x, height pixels for y
|
# width pixels for x, height pixels for y
|
||||||
|
@ -27,7 +27,7 @@ TOL = 1e-2
|
|||||||
class Vector(object):
|
class Vector(object):
|
||||||
"""Create a 3-dimensional vector
|
"""Create a 3-dimensional vector
|
||||||
|
|
||||||
:param args: a 3-d vector, with x-y-z parts.
|
:param args: a 3D vector, with x-y-z parts.
|
||||||
|
|
||||||
you can either provide:
|
you can either provide:
|
||||||
* nothing (in which case the null vector is return)
|
* nothing (in which case the null vector is return)
|
||||||
@ -166,7 +166,7 @@ class Vector(object):
|
|||||||
"""Return the vector itself
|
"""Return the vector itself
|
||||||
|
|
||||||
The center of myself is myself.
|
The center of myself is myself.
|
||||||
Provided so that vectors, vertexes, and other shapes all support a
|
Provided so that vectors, vertices, and other shapes all support a
|
||||||
common interface, when Center() is requested for all objects on the
|
common interface, when Center() is requested for all objects on the
|
||||||
stack.
|
stack.
|
||||||
"""
|
"""
|
||||||
@ -375,6 +375,14 @@ class Matrix:
|
|||||||
else:
|
else:
|
||||||
raise IndexError("Out of bounds access into 4x4 matrix: {!r}".format(rc))
|
raise IndexError("Out of bounds access into 4x4 matrix: {!r}".format(rc))
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
"""
|
||||||
|
Generate a valid python expression representing this Matrix
|
||||||
|
"""
|
||||||
|
matrix_transposed = self.transposed_list()
|
||||||
|
matrix_str = ",\n ".join(str(matrix_transposed[i::4]) for i in range(4))
|
||||||
|
return f"Matrix([{matrix_str}])"
|
||||||
|
|
||||||
|
|
||||||
class Plane(object):
|
class Plane(object):
|
||||||
"""A 2D coordinate system in space
|
"""A 2D coordinate system in space
|
||||||
@ -382,7 +390,7 @@ class Plane(object):
|
|||||||
A 2D coordinate system in space, with the x-y axes on the plane, and a
|
A 2D coordinate system in space, with the x-y axes on the plane, and a
|
||||||
particular point as the origin.
|
particular point as the origin.
|
||||||
|
|
||||||
A plane allows the use of 2-d coordinates, which are later converted to
|
A plane allows the use of 2D coordinates, which are later converted to
|
||||||
global, 3d coordinates when the operations are complete.
|
global, 3d coordinates when the operations are complete.
|
||||||
|
|
||||||
Frequently, it is not necessary to create work planes, as they can be
|
Frequently, it is not necessary to create work planes, as they can be
|
||||||
@ -592,7 +600,7 @@ class Plane(object):
|
|||||||
:param float y: offset in the y direction
|
:param float y: offset in the y direction
|
||||||
:return: void
|
:return: void
|
||||||
|
|
||||||
The new coordinates are specified in terms of the current 2-d system.
|
The new coordinates are specified in terms of the current 2D system.
|
||||||
As an example:
|
As an example:
|
||||||
|
|
||||||
p = Plane.XY()
|
p = Plane.XY()
|
||||||
@ -614,9 +622,9 @@ class Plane(object):
|
|||||||
|
|
||||||
|
|
||||||
Most of the time, the z-coordinate returned will be zero, because most
|
Most of the time, the z-coordinate returned will be zero, because most
|
||||||
operations based on a plane are all 2-d. Occasionally, though, 3-d
|
operations based on a plane are all 2D. Occasionally, though, 3D
|
||||||
points outside of the current plane are transformed. One such example is
|
points outside of the current plane are transformed. One such example is
|
||||||
:py:meth:`Workplane.box`, where 3-d corners of a box are transformed to
|
:py:meth:`Workplane.box`, where 3D corners of a box are transformed to
|
||||||
orient the box in space correctly.
|
orient the box in space correctly.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -706,7 +714,7 @@ class Plane(object):
|
|||||||
for w in listOfShapes:
|
for w in listOfShapes:
|
||||||
mirrored = w.transformShape(Matrix(T))
|
mirrored = w.transformShape(Matrix(T))
|
||||||
|
|
||||||
# attemp stitching of the wires
|
# attempt stitching of the wires
|
||||||
resultWires.append(mirrored)
|
resultWires.append(mirrored)
|
||||||
|
|
||||||
return resultWires
|
return resultWires
|
||||||
|
@ -136,7 +136,7 @@ def _dxf_spline(el):
|
|||||||
knots.SetValue(i + 1, k)
|
knots.SetValue(i + 1, k)
|
||||||
multiplicities.SetValue(i + 1, m)
|
multiplicities.SetValue(i + 1, m)
|
||||||
|
|
||||||
# assemble wieghts if present:
|
# assemble weights if present:
|
||||||
if el.weights:
|
if el.weights:
|
||||||
rational = True
|
rational = True
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ def _dxf_spline(el):
|
|||||||
for i, w in enumerate(el.weights):
|
for i, w in enumerate(el.weights):
|
||||||
weights.SetValue(i + 1, w)
|
weights.SetValue(i + 1, w)
|
||||||
|
|
||||||
# assmeble conotrol points
|
# assemble control points
|
||||||
pts = TColgp_Array1OfPnt(1, len(el.control_points))
|
pts = TColgp_Array1OfPnt(1, len(el.control_points))
|
||||||
for i, p in enumerate(el.control_points):
|
for i, p in enumerate(el.control_points):
|
||||||
pts.SetValue(i + 1, gp_Pnt(*p))
|
pts.SetValue(i + 1, gp_Pnt(*p))
|
||||||
|
@ -98,7 +98,7 @@ from OCP.BRepPrimAPI import (
|
|||||||
|
|
||||||
from OCP.TopExp import TopExp_Explorer # Toplogy explorer
|
from OCP.TopExp import TopExp_Explorer # Toplogy explorer
|
||||||
|
|
||||||
# used for getting underlying geoetry -- is this equvalent to brep adaptor?
|
# used for getting underlying geoetry -- is this equivalent to brep adaptor?
|
||||||
from OCP.BRep import BRep_Tool, BRep_Builder
|
from OCP.BRep import BRep_Tool, BRep_Builder
|
||||||
|
|
||||||
from OCP.TopoDS import (
|
from OCP.TopoDS import (
|
||||||
@ -420,7 +420,7 @@ class Shape(object):
|
|||||||
}
|
}
|
||||||
|
|
||||||
t = shapetype(obj)
|
t = shapetype(obj)
|
||||||
# NB downcast is nedded to handly TopoDS_Shape types
|
# NB downcast is needed to handly TopoDS_Shape types
|
||||||
tr = constructor_LUT[t](downcast(obj))
|
tr = constructor_LUT[t](downcast(obj))
|
||||||
tr.forConstruction = forConstruction
|
tr.forConstruction = forConstruction
|
||||||
|
|
||||||
@ -1045,7 +1045,7 @@ class Shape(object):
|
|||||||
|
|
||||||
def mesh(self, tolerance: float, angularTolerance: float = 0.1):
|
def mesh(self, tolerance: float, angularTolerance: float = 0.1):
|
||||||
"""
|
"""
|
||||||
Generate traingulation if none exists.
|
Generate triangulation if none exists.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not BRepTools.Triangulation_s(self.wrapped, tolerance):
|
if not BRepTools.Triangulation_s(self.wrapped, tolerance):
|
||||||
@ -1115,7 +1115,7 @@ class Shape(object):
|
|||||||
|
|
||||||
rv = shape_data.getVtkPolyData()
|
rv = shape_data.getVtkPolyData()
|
||||||
|
|
||||||
# convert to traingles and split edges
|
# convert to triangles and split edges
|
||||||
t_filter = vtkTriangleFilter()
|
t_filter = vtkTriangleFilter()
|
||||||
t_filter.SetInputData(rv)
|
t_filter.SetInputData(rv)
|
||||||
t_filter.Update()
|
t_filter.Update()
|
||||||
@ -1353,7 +1353,7 @@ class Mixin1D(object):
|
|||||||
d: float,
|
d: float,
|
||||||
mode: Literal["length", "parameter"] = "length",
|
mode: Literal["length", "parameter"] = "length",
|
||||||
) -> Vector:
|
) -> Vector:
|
||||||
"""Generate a postion along the underlying curve.
|
"""Generate a position along the underlying curve.
|
||||||
:param d: distance or parameter value
|
:param d: distance or parameter value
|
||||||
:param mode: position calculation mode (default: length)
|
:param mode: position calculation mode (default: length)
|
||||||
:return: A Vector on the underlying curve located at the specified d value.
|
:return: A Vector on the underlying curve located at the specified d value.
|
||||||
@ -1567,8 +1567,8 @@ class Edge(Shape, Mixin1D):
|
|||||||
|
|
||||||
:param listOfVector: a list of Vectors that represent the points
|
:param listOfVector: a list of Vectors that represent the points
|
||||||
:param tangents: tuple of Vectors specifying start and finish tangent
|
:param tangents: tuple of Vectors specifying start and finish tangent
|
||||||
:param periodic: creation of peridic curves
|
:param periodic: creation of periodic curves
|
||||||
:param parameters: the value of the parameter at each interpolation point. (The intepolated
|
:param parameters: the value of the parameter at each interpolation point. (The interpolated
|
||||||
curve is represented as a vector-valued function of a scalar parameter.) If periodic ==
|
curve is represented as a vector-valued function of a scalar parameter.) If periodic ==
|
||||||
True, then len(parameters) must be len(intepolation points) + 1, otherwise len(parameters)
|
True, then len(parameters) must be len(intepolation points) + 1, otherwise len(parameters)
|
||||||
must be equal to len(interpolation points).
|
must be equal to len(interpolation points).
|
||||||
@ -1899,7 +1899,7 @@ class Wire(Shape, Mixin1D):
|
|||||||
gp_Ax3(center.toPnt(), dir.toDir()), angle * DEG2RAD, radius
|
gp_Ax3(center.toPnt(), dir.toDir()), angle * DEG2RAD, radius
|
||||||
)
|
)
|
||||||
|
|
||||||
# 2. construct an semgent in the u,v domain
|
# 2. construct an segment in the u,v domain
|
||||||
if lefthand:
|
if lefthand:
|
||||||
geom_line = Geom2d_Line(gp_Pnt2d(0.0, 0.0), gp_Dir2d(-2 * pi, pitch))
|
geom_line = Geom2d_Line(gp_Pnt2d(0.0, 0.0), gp_Dir2d(-2 * pi, pitch))
|
||||||
else:
|
else:
|
||||||
@ -2415,7 +2415,7 @@ class Mixin3D(object):
|
|||||||
object within the specified tolerance.
|
object within the specified tolerance.
|
||||||
|
|
||||||
:param point: tuple or Vector representing 3D point to be tested
|
:param point: tuple or Vector representing 3D point to be tested
|
||||||
:param tolerance: tolerence for inside determination, default=1.0e-6
|
:param tolerance: tolerance for inside determination, default=1.0e-6
|
||||||
:return: bool indicating whether or not point is within solid
|
:return: bool indicating whether or not point is within solid
|
||||||
"""
|
"""
|
||||||
if isinstance(point, Vector):
|
if isinstance(point, Vector):
|
||||||
@ -2765,7 +2765,7 @@ class Solid(Shape, Mixin3D):
|
|||||||
straight_spine_e = Edge.makeLine(vecCenter, vecCenter.add(vecNormal))
|
straight_spine_e = Edge.makeLine(vecCenter, vecCenter.add(vecNormal))
|
||||||
straight_spine_w = Wire.combine([straight_spine_e,])[0].wrapped
|
straight_spine_w = Wire.combine([straight_spine_e,])[0].wrapped
|
||||||
|
|
||||||
# make an auxliliary spine
|
# make an auxiliary spine
|
||||||
pitch = 360.0 / angleDegrees * vecNormal.Length
|
pitch = 360.0 / angleDegrees * vecNormal.Length
|
||||||
radius = 1
|
radius = 1
|
||||||
aux_spine_w = Wire.makeHelix(
|
aux_spine_w = Wire.makeHelix(
|
||||||
@ -2783,7 +2783,7 @@ class Solid(Shape, Mixin3D):
|
|||||||
for w in innerWires
|
for w in innerWires
|
||||||
]
|
]
|
||||||
|
|
||||||
# combine the inner solids into compund
|
# combine the inner solids into compound
|
||||||
inner_comp = Compound._makeCompound(inner_solids)
|
inner_comp = Compound._makeCompound(inner_solids)
|
||||||
|
|
||||||
# subtract from the outer solid
|
# subtract from the outer solid
|
||||||
@ -2933,7 +2933,7 @@ class Solid(Shape, Mixin3D):
|
|||||||
:param outerWire: the outermost wire
|
:param outerWire: the outermost wire
|
||||||
:param innerWires: a list of inner wires
|
:param innerWires: a list of inner wires
|
||||||
:param path: The wire to sweep the face resulting from the wires over
|
:param path: The wire to sweep the face resulting from the wires over
|
||||||
:param boolean makeSolid: return Solid or Shell (defualt True)
|
:param boolean makeSolid: return Solid or Shell (default True)
|
||||||
:param boolean isFrenet: Frenet mode (default False)
|
:param boolean isFrenet: Frenet mode (default False)
|
||||||
:param mode: additional sweep mode parameters.
|
:param mode: additional sweep mode parameters.
|
||||||
:param transitionMode:
|
:param transitionMode:
|
||||||
@ -3027,7 +3027,7 @@ class Solid(Shape, Mixin3D):
|
|||||||
"""
|
"""
|
||||||
Make a prismatic feature (additive or subtractive)
|
Make a prismatic feature (additive or subtractive)
|
||||||
|
|
||||||
:param basis: face to perfrom the operation on
|
:param basis: face to perform the operation on
|
||||||
:param profiles: list of profiles
|
:param profiles: list of profiles
|
||||||
:param depth: depth of the cut or extrusion
|
:param depth: depth of the cut or extrusion
|
||||||
:param thruAll: cut thruAll
|
:param thruAll: cut thruAll
|
||||||
|
@ -214,7 +214,7 @@ class ParallelDirSelector(BaseDirSelector):
|
|||||||
|
|
||||||
CQ(aCube).faces(ParallelDirSelector((0, 0, 1))
|
CQ(aCube).faces(ParallelDirSelector((0, 0, 1))
|
||||||
|
|
||||||
selects faces with a normals in the z direction, and is equivalent to::
|
selects faces with the normal parallel to the z direction, and is equivalent to::
|
||||||
|
|
||||||
CQ(aCube).faces("|Z")
|
CQ(aCube).faces("|Z")
|
||||||
"""
|
"""
|
||||||
@ -237,7 +237,7 @@ class DirectionSelector(BaseDirSelector):
|
|||||||
|
|
||||||
CQ(aCube).faces(DirectionSelector((0, 0, 1))
|
CQ(aCube).faces(DirectionSelector((0, 0, 1))
|
||||||
|
|
||||||
selects faces with a normals in the z direction, and is equivalent to::
|
selects faces with the normal in the z direction, and is equivalent to::
|
||||||
|
|
||||||
CQ(aCube).faces("+Z")
|
CQ(aCube).faces("+Z")
|
||||||
"""
|
"""
|
||||||
@ -261,7 +261,7 @@ class PerpendicularDirSelector(BaseDirSelector):
|
|||||||
|
|
||||||
CQ(aCube).faces(PerpendicularDirSelector((0, 0, 1))
|
CQ(aCube).faces(PerpendicularDirSelector((0, 0, 1))
|
||||||
|
|
||||||
selects faces with a normals perpendicular to the z direction, and is equivalent to::
|
selects faces with the normal perpendicular to the z direction, and is equivalent to::
|
||||||
|
|
||||||
CQ(aCube).faces("#Z")
|
CQ(aCube).faces("#Z")
|
||||||
"""
|
"""
|
||||||
@ -586,7 +586,7 @@ class SumSelector(BinarySelector):
|
|||||||
|
|
||||||
class SubtractSelector(BinarySelector):
|
class SubtractSelector(BinarySelector):
|
||||||
"""
|
"""
|
||||||
Difference selector. Substract results of a selector from another
|
Difference selector. Subtract results of a selector from another
|
||||||
selectors results.
|
selectors results.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -842,7 +842,7 @@ class StringSyntaxSelector(Selector):
|
|||||||
|
|
||||||
:return: objects that match the specified selector
|
:return: objects that match the specified selector
|
||||||
|
|
||||||
***Modfiers*** are ``('|','+','-','<','>','%')``
|
***Modifiers*** are ``('|','+','-','<','>','%')``
|
||||||
|
|
||||||
:\|:
|
:\|:
|
||||||
parallel to ( same as :py:class:`ParallelDirSelector` ). Can return multiple objects.
|
parallel to ( same as :py:class:`ParallelDirSelector` ). Can return multiple objects.
|
||||||
@ -862,7 +862,7 @@ class StringSyntaxSelector(Selector):
|
|||||||
***axisStrings*** are: ``X,Y,Z,XY,YZ,XZ`` or ``(x,y,z)`` which defines an arbitrary direction
|
***axisStrings*** are: ``X,Y,Z,XY,YZ,XZ`` or ``(x,y,z)`` which defines an arbitrary direction
|
||||||
|
|
||||||
It is possible to combine simple selectors together using logical operations.
|
It is possible to combine simple selectors together using logical operations.
|
||||||
The following operations are suuported
|
The following operations are supported
|
||||||
|
|
||||||
:and:
|
:and:
|
||||||
Logical AND, e.g. >X and >Y
|
Logical AND, e.g. >X and >Y
|
||||||
|
@ -15,7 +15,7 @@ requirements:
|
|||||||
- setuptools
|
- setuptools
|
||||||
run:
|
run:
|
||||||
- python {{ environ.get('PYTHON_VERSION') }}
|
- python {{ environ.get('PYTHON_VERSION') }}
|
||||||
- ocp 7.5.1
|
- ocp 7.5.2
|
||||||
- pyparsing 2.*
|
- pyparsing 2.*
|
||||||
- ezdxf
|
- ezdxf
|
||||||
- ipython
|
- ipython
|
||||||
|
2
doc/_static/cadquery_cheatsheet.html
vendored
2
doc/_static/cadquery_cheatsheet.html
vendored
@ -153,7 +153,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Workplane(inPlane[origin, obj])</td>
|
<td>Workplane(inPlane[origin, obj])</td>
|
||||||
<td>Defines a coordinate system in space, in which 2-d coordinates can be used.</td>
|
<td>Defines a coordinate system in space, in which 2D coordinates can be used.</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,7 +6,7 @@ CadQuery API Reference
|
|||||||
|
|
||||||
The CadQuery API is made up of 2 main objects:
|
The CadQuery API is made up of 2 main objects:
|
||||||
|
|
||||||
* **Workplane** -- Wraps a topological entity and provides a 2-D modelling context.
|
* **Workplane** -- Wraps a topological entity and provides a 2D modelling context.
|
||||||
* **Selector** -- Filter and select things
|
* **Selector** -- Filter and select things
|
||||||
|
|
||||||
This page lists methods of these objects grouped by **functional area**
|
This page lists methods of these objects grouped by **functional area**
|
||||||
@ -29,12 +29,12 @@ Creating new workplanes and object chains
|
|||||||
|
|
||||||
.. _2dOperations:
|
.. _2dOperations:
|
||||||
|
|
||||||
2-d Operations
|
2D Operations
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
Creating 2-d constructs that can be used to create 3 d features.
|
Creating 2D constructs that can be used to create 3D features.
|
||||||
|
|
||||||
All 2-d operations require a **Workplane** object to be created.
|
All 2D operations require a **Workplane** object to be created.
|
||||||
|
|
||||||
.. currentmodule:: cadquery
|
.. currentmodule:: cadquery
|
||||||
|
|
||||||
@ -73,12 +73,12 @@ All 2-d operations require a **Workplane** object to be created.
|
|||||||
|
|
||||||
.. _3doperations:
|
.. _3doperations:
|
||||||
|
|
||||||
3-d Operations
|
3D Operations
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
Some 3-d operations also require an active 2-d workplane, but some do not.
|
Some 3D operations also require an active 2D workplane, but some do not.
|
||||||
|
|
||||||
3-d operations that require a 2-d workplane to be active:
|
3D operations that require a 2D workplane to be active:
|
||||||
|
|
||||||
.. autosummary::
|
.. autosummary::
|
||||||
Workplane.cboreHole
|
Workplane.cboreHole
|
||||||
@ -90,6 +90,7 @@ Some 3-d operations also require an active 2-d workplane, but some do not.
|
|||||||
Workplane.cutThruAll
|
Workplane.cutThruAll
|
||||||
Workplane.box
|
Workplane.box
|
||||||
Workplane.sphere
|
Workplane.sphere
|
||||||
|
Workplane.cylinder
|
||||||
Workplane.union
|
Workplane.union
|
||||||
Workplane.combine
|
Workplane.combine
|
||||||
Workplane.intersect
|
Workplane.intersect
|
||||||
@ -100,7 +101,7 @@ Some 3-d operations also require an active 2-d workplane, but some do not.
|
|||||||
Workplane.text
|
Workplane.text
|
||||||
|
|
||||||
|
|
||||||
3-d operations that do NOT require a 2-d workplane to be active:
|
3D operations that do NOT require a 2D workplane to be active:
|
||||||
|
|
||||||
.. autosummary::
|
.. autosummary::
|
||||||
Workplane.shell
|
Workplane.shell
|
||||||
@ -167,7 +168,7 @@ Selectors
|
|||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
Objects that filter and select CAD objects. Selectors are used to select existing geometry
|
Objects that filter and select CAD objects. Selectors are used to select existing geometry
|
||||||
as a basis for futher operations.
|
as a basis for further operations.
|
||||||
|
|
||||||
.. currentmodule:: cadquery.selectors
|
.. currentmodule:: cadquery.selectors
|
||||||
.. autosummary::
|
.. autosummary::
|
||||||
|
879
doc/assy.rst
879
doc/assy.rst
@ -1,11 +1,11 @@
|
|||||||
.. _assytutorial:
|
.. _assytutorial:
|
||||||
|
|
||||||
***********************
|
**********
|
||||||
Assembly Tutorial
|
Assemblies
|
||||||
***********************
|
**********
|
||||||
|
|
||||||
Introduction
|
Assembly tutorial
|
||||||
============
|
-----------------
|
||||||
|
|
||||||
The purpose of this section is to demonstrate how to use the assembly and constraints
|
The purpose of this section is to demonstrate how to use the assembly and constraints
|
||||||
functionality to build a realistic model. It will be a enclosure door assembly made out of 20x20 v-slot profiles.
|
functionality to build a realistic model. It will be a enclosure door assembly made out of 20x20 v-slot profiles.
|
||||||
@ -373,3 +373,872 @@ STEP can be loaded in all CAD tool, e.g. in FreeCAD and the XML be used in other
|
|||||||
In the case of STEP colors are preserved but not transparency.
|
In the case of STEP colors are preserved but not transparency.
|
||||||
|
|
||||||
.. image:: _static/door_assy_freecad.png
|
.. image:: _static/door_assy_freecad.png
|
||||||
|
|
||||||
|
|
||||||
|
Object locations
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Objects can be added to an assembly with initial locations supplied, such as:
|
||||||
|
|
||||||
|
.. cadquery::
|
||||||
|
|
||||||
|
import cadquery as cq
|
||||||
|
|
||||||
|
cone = cq.Solid.makeCone(1, 0, 2)
|
||||||
|
|
||||||
|
assy = cq.Assembly()
|
||||||
|
assy.add(
|
||||||
|
cone,
|
||||||
|
loc=cq.Location(cq.Vector(0, 0, 0), cq.Vector(1, 0, 0), 180),
|
||||||
|
name="cone0",
|
||||||
|
color=cq.Color("green")
|
||||||
|
)
|
||||||
|
assy.add(cone, name="cone1", color=cq.Color("blue"))
|
||||||
|
|
||||||
|
show_object(assy)
|
||||||
|
|
||||||
|
|
||||||
|
As an alternative to the user calculating locations, constraints and the method
|
||||||
|
:meth:`~cadquery.Assembly.solve` can be used to position objects in an assembly.
|
||||||
|
|
||||||
|
If initial locations and the method :meth:`~cadquery.Assembly.solve` are used the solver will
|
||||||
|
overwrite these initial locations with it's solution, however initial locations can still affect the
|
||||||
|
final solution. In an underconstrained system the solver may not move an object if it does not
|
||||||
|
contribute to the cost function, or if multiple solutions exist (ie. multiple instances
|
||||||
|
where the cost function is at a minimum) initial locations can cause the solver to converge on one
|
||||||
|
particular solution. For very complicated assemblies setting approximately correct initial locations
|
||||||
|
can also reduce the computational time requred.
|
||||||
|
|
||||||
|
|
||||||
|
Constraints
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Constraints are often a better representation of the real world relationship the user wants to
|
||||||
|
model than directly supplying locations. In the above example the real world relationship is that
|
||||||
|
the bottom face of each cone should touch, which can be modelled with a Plane constraint. When the
|
||||||
|
user provides explicit locations (instead of constraints) then they are also reponsible for updating
|
||||||
|
them when, for example, the location of ``cone1`` changes.
|
||||||
|
|
||||||
|
When at least one constraint is supplied and the method :meth:`~cadquery.Assembly.solve` is run, an
|
||||||
|
optimization problem is set up. Each constraint provides a cost function that depends on the
|
||||||
|
position and orientation (represented by a :class:`~cadquery.Location`) of the two objects specified
|
||||||
|
when creating the constraint. The solver varies the location of the assembly's children and attempts
|
||||||
|
to minimize the sum of all cost functions. Hence by reading the formulae of the cost functions
|
||||||
|
below, you can understand exactly what each constraint does.
|
||||||
|
|
||||||
|
|
||||||
|
Point
|
||||||
|
=====
|
||||||
|
|
||||||
|
The Point constraint is a frequently used constraint that minimizes the distance between two points.
|
||||||
|
Some example uses are centering faces or aligning verticies, but it is also useful with dummy
|
||||||
|
vertices to create offsets between two parts.
|
||||||
|
|
||||||
|
The cost function is:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
( param - \lvert \vec{ c_1 } - \vec{ c_2 } \rvert ) ^2
|
||||||
|
|
||||||
|
Where:
|
||||||
|
|
||||||
|
- :math:`param` is the parameter of the constraint, which defaults to 0,
|
||||||
|
- :math:`\vec{ c_i }` is the center of the ith object, and
|
||||||
|
- :math:`\lvert \vec{ v } \rvert` is the modulus of :math:`\vec{ v }`, ie. the length of
|
||||||
|
:math:`\vec{ v }`.
|
||||||
|
|
||||||
|
When creating a Point constraint, the ``param`` argument can be used to specify a desired offset
|
||||||
|
between the two centers. This offset does not have a direction associated with it, if you want to
|
||||||
|
specify an offset in a specific direction then you should use a dummy :class:`~cadquery.Vertex`.
|
||||||
|
|
||||||
|
The Point constraint uses the :meth:`~cadquery.occ_impl.Shape.Center` to find the center of the
|
||||||
|
argument. Hence it will work with all subclasses of :class:`~caquery.occ_impl.Shape`.
|
||||||
|
|
||||||
|
.. cadquery::
|
||||||
|
|
||||||
|
import cadquery as cq
|
||||||
|
|
||||||
|
# Use the Point constraint to position boxes relative to an arc
|
||||||
|
line = cq.Edge.makeCircle(radius=10, angle1=0, angle2=90)
|
||||||
|
box = cq.Workplane().box(1, 1, 1)
|
||||||
|
|
||||||
|
assy = cq.Assembly()
|
||||||
|
assy.add(line, name="line")
|
||||||
|
|
||||||
|
# position the red box on the center of the arc
|
||||||
|
assy.add(box, name="box0", color=cq.Color("red"))
|
||||||
|
assy.constrain("line", "box0", "Point")
|
||||||
|
|
||||||
|
# position the green box at a normalized distance of 0.8 along the arc
|
||||||
|
position0 = line.positionAt(0.8)
|
||||||
|
assy.add(box, name="box1", color=cq.Color("green"))
|
||||||
|
assy.constrain(
|
||||||
|
"line", cq.Vertex.makeVertex(*position0.toTuple()), "box1", box.val(), "Point",
|
||||||
|
)
|
||||||
|
|
||||||
|
# position the orange box 2 units in any direction from the green box
|
||||||
|
assy.add(box, name="box2", color=cq.Color("orange"))
|
||||||
|
assy.constrain(
|
||||||
|
"line",
|
||||||
|
cq.Vertex.makeVertex(*position0.toTuple()),
|
||||||
|
"box2",
|
||||||
|
box.val(),
|
||||||
|
"Point",
|
||||||
|
param=2,
|
||||||
|
)
|
||||||
|
|
||||||
|
# position the blue box offset 2 units in the x direction from the green box
|
||||||
|
position1 = position0 + cq.Vector(2, 0, 0)
|
||||||
|
assy.add(box, name="box3", color=cq.Color("blue"))
|
||||||
|
assy.constrain(
|
||||||
|
"line", cq.Vertex.makeVertex(*position1.toTuple()), "box3", box.val(), "Point",
|
||||||
|
)
|
||||||
|
|
||||||
|
assy.solve()
|
||||||
|
show_object(assy)
|
||||||
|
|
||||||
|
|
||||||
|
Axis
|
||||||
|
====
|
||||||
|
|
||||||
|
The Axis constraint minimizes the angle between two vectors. It is frequently used to align faces
|
||||||
|
and control the rotation of an object.
|
||||||
|
|
||||||
|
The cost function is:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
( k_{ dir } \times ( param - \vec{ d_1 } \angle \vec{ d_2 } ) ^2
|
||||||
|
|
||||||
|
|
||||||
|
Where:
|
||||||
|
|
||||||
|
- :math:`k_{ dir }` is a scaling factor for directional constraints,
|
||||||
|
- :math:`param` is the parameter of the constraint, which defaults to :math:`\pi` radians,
|
||||||
|
- :math:`\vec{d_i}` is the direction created from the ith object argument as described below, and
|
||||||
|
- :math:`\vec{ d_1 } \angle \vec{ d_2 }` is the angle in radians between :math:`\vec{ d_1 }` and
|
||||||
|
:math:`\vec{ d_2 }`.
|
||||||
|
|
||||||
|
|
||||||
|
The argument ``param`` defaults to :math:`\pi` radians, which sets the two directions opposite
|
||||||
|
to each other. This represents what is often called a "mate" relationship, where the external faces
|
||||||
|
of two objects touch.
|
||||||
|
|
||||||
|
|
||||||
|
.. cadquery::
|
||||||
|
|
||||||
|
import cadquery as cq
|
||||||
|
|
||||||
|
cone = cq.Solid.makeCone(1, 0, 2)
|
||||||
|
|
||||||
|
assy = cq.Assembly()
|
||||||
|
assy.add(cone, name="cone0", color=cq.Color("green"))
|
||||||
|
assy.add(cone, name="cone1", color=cq.Color("blue"))
|
||||||
|
assy.constrain("cone0@faces@<Z", "cone1@faces@<Z", "Axis")
|
||||||
|
|
||||||
|
assy.solve()
|
||||||
|
show_object(assy)
|
||||||
|
|
||||||
|
|
||||||
|
If the ``param`` argument is set to zero, then the two objects will point in the same direction.
|
||||||
|
This is often used when one object goes through another, such as a pin going into a hole in a plate:
|
||||||
|
|
||||||
|
|
||||||
|
.. cadquery::
|
||||||
|
|
||||||
|
import cadquery as cq
|
||||||
|
|
||||||
|
plate = cq.Workplane().box(10, 10, 1).faces(">Z").workplane().hole(2)
|
||||||
|
cone = cq.Solid.makeCone(0.8, 0, 4)
|
||||||
|
|
||||||
|
assy = cq.Assembly()
|
||||||
|
assy.add(plate, name="plate", color=cq.Color("green"))
|
||||||
|
assy.add(cone, name="cone", color=cq.Color("blue"))
|
||||||
|
# place the center of the flat face of the cone in the center of the upper face of the plate
|
||||||
|
assy.constrain("plate@faces@>Z", "cone@faces@<Z", "Point")
|
||||||
|
|
||||||
|
# set both the flat face of the cone and the upper face of the plate to point in the same direction
|
||||||
|
assy.constrain("plate@faces@>Z", "cone@faces@<Z", "Axis", param=0)
|
||||||
|
|
||||||
|
assy.solve()
|
||||||
|
show_object(assy)
|
||||||
|
|
||||||
|
|
||||||
|
In creating an Axis constraint, a direction vector is extracted in one of three different ways,
|
||||||
|
depending on the object's type.
|
||||||
|
|
||||||
|
:class:`~cadquery.Face`:
|
||||||
|
Using :meth:`~cadquery.Face.normalAt`
|
||||||
|
|
||||||
|
:class:`~cadquery.Edge` and :meth:`~cadquery.Shape.geomType` is ``"CIRCLE"``:
|
||||||
|
Using :meth:`~cadquery.Mixin1D.normal`
|
||||||
|
|
||||||
|
:class:`~cadquery.Edge` and :meth:`~cadquery.Shape.geomType` is not ``"CIRCLE"``:
|
||||||
|
Using :meth:`~cadquery.Mixin1D.tangentAt`
|
||||||
|
|
||||||
|
Using any other type of object will raise a :exc:`ValueError`. By far the most common use case
|
||||||
|
is to define an Axis constraint from a :class:`~cadquery.Face`.
|
||||||
|
|
||||||
|
|
||||||
|
.. cadquery::
|
||||||
|
|
||||||
|
import cadquery as cq
|
||||||
|
from math import cos, sin, pi
|
||||||
|
|
||||||
|
# Create a sinusoidal surface:
|
||||||
|
surf = cq.Workplane().parametricSurface(
|
||||||
|
lambda u, v: (u, v, 5 * sin(pi * u / 10) * cos(pi * v / 10)),
|
||||||
|
N=40,
|
||||||
|
start=0,
|
||||||
|
stop=20,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create a cone with a small, flat tip:
|
||||||
|
cone = (
|
||||||
|
cq.Workplane()
|
||||||
|
.add(cq.Solid.makeCone(1, 0.1, 2))
|
||||||
|
# tag the tip for easy reference in the constraint:
|
||||||
|
.faces(">Z")
|
||||||
|
.tag("tip")
|
||||||
|
.end()
|
||||||
|
)
|
||||||
|
|
||||||
|
assy = cq.Assembly()
|
||||||
|
assy.add(surf, name="surf", color=cq.Color("lightgray"))
|
||||||
|
assy.add(cone, name="cone", color=cq.Color("green"))
|
||||||
|
# set the Face on the tip of the cone to point in
|
||||||
|
# the opposite direction of the center of the surface:
|
||||||
|
assy.constrain("surf", "cone?tip", "Axis")
|
||||||
|
# to make the example clearer, move the cone to the center of the face:
|
||||||
|
assy.constrain("surf", "cone?tip", "Point")
|
||||||
|
assy.solve()
|
||||||
|
|
||||||
|
show_object(assy)
|
||||||
|
|
||||||
|
|
||||||
|
Plane
|
||||||
|
=====
|
||||||
|
|
||||||
|
The Plane constraint is simply a combination of both the Point and Axis constraints. It is a
|
||||||
|
convienient shortcut for a commonly used combination of constraints. It can be used to shorten the
|
||||||
|
previous example from the two constraints to just one:
|
||||||
|
|
||||||
|
.. code-block:: diff
|
||||||
|
|
||||||
|
assy = cq.Assembly()
|
||||||
|
assy.add(surf, name="surf", color=cq.Color("lightgray"))
|
||||||
|
assy.add(cone, name="cone", color=cq.Color("green"))
|
||||||
|
-# set the Face on the tip of the cone to point in
|
||||||
|
-# the opposite direction of the center of the surface:
|
||||||
|
-assy.constrain("surf", "cone?tip", "Axis")
|
||||||
|
-# to make the example clearer, move the cone to the center of the face:
|
||||||
|
-assy.constrain("surf", "cone?tip", "Point")
|
||||||
|
+assy.constrain("surf", "cone?tip", "Plane")
|
||||||
|
assy.solve()
|
||||||
|
|
||||||
|
show_object(assy)
|
||||||
|
|
||||||
|
|
||||||
|
The result of this code is identical to the above two constraint example.
|
||||||
|
|
||||||
|
For the cost function of Plane, please see the Point and Axis sections. The ``param`` argument is
|
||||||
|
copied into both constraints and should be left as the default value of ``None`` for a "mate" style
|
||||||
|
constraint (two surfaces touching) or can be set to ``0`` for a through surface constraint (see
|
||||||
|
desciption in the Axis constraint section).
|
||||||
|
|
||||||
|
|
||||||
|
PointInPlane
|
||||||
|
============
|
||||||
|
|
||||||
|
PointInPlane positions the center of the first object within the plane defined by the second object.
|
||||||
|
The cost function is:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
\operatorname{dist}( \vec{ c }, p_\text{ offset } ) ^2
|
||||||
|
|
||||||
|
|
||||||
|
Where:
|
||||||
|
|
||||||
|
- :math:`\vec{ c }` is the center of the first argument,
|
||||||
|
- :math:`p_\text{ offset }` is a plane created from the second object, offset in the plane's normal
|
||||||
|
direction by ``param``, and
|
||||||
|
- :math:`\operatorname{dist}( \vec{ a }, b)` is the distance between point :math:`\vec{ a }` and
|
||||||
|
plane :math:`b`.
|
||||||
|
|
||||||
|
|
||||||
|
.. cadquery::
|
||||||
|
|
||||||
|
import cadquery as cq
|
||||||
|
|
||||||
|
# Create an L-shaped object:
|
||||||
|
bracket = (
|
||||||
|
cq.Workplane("YZ")
|
||||||
|
.hLine(1)
|
||||||
|
.vLine(0.1)
|
||||||
|
.hLineTo(0.2)
|
||||||
|
.vLineTo(1)
|
||||||
|
.hLineTo(0)
|
||||||
|
.close()
|
||||||
|
.extrude(1)
|
||||||
|
# tag some faces for easy reference:
|
||||||
|
.faces(">Y[1]")
|
||||||
|
.tag("inner_vert")
|
||||||
|
.end()
|
||||||
|
.faces(">Z[1]")
|
||||||
|
.tag("inner_horiz")
|
||||||
|
.end()
|
||||||
|
)
|
||||||
|
|
||||||
|
box = cq.Workplane().box(0.5, 0.5, 0.5)
|
||||||
|
|
||||||
|
assy = cq.Assembly()
|
||||||
|
assy.add(bracket, name="bracket", color=cq.Color("gray"))
|
||||||
|
assy.add(box, name="box", color=cq.Color("green"))
|
||||||
|
|
||||||
|
# lock bracket orientation:
|
||||||
|
assy.constrain("bracket@faces@>Z", "box@faces@>Z", "Axis", param=0)
|
||||||
|
assy.constrain("bracket@faces@>X", "box@faces@>X", "Axis", param=0)
|
||||||
|
|
||||||
|
# constrain the bottom of the box to be on the plane defined by inner_horiz:
|
||||||
|
assy.constrain("box@faces@<Z", "bracket?inner_horiz", "PointInPlane")
|
||||||
|
# constrain the side of the box to be 0.2 units from the plane defined by inner_vert
|
||||||
|
assy.constrain("box@faces@<Y", "bracket?inner_vert", "PointInPlane", param=0.2)
|
||||||
|
# constrain the end of the box to be 0.1 units inside the end of the bracket
|
||||||
|
assy.constrain("box@faces@>X", "bracket@faces@>X", "PointInPlane", param=-0.1)
|
||||||
|
|
||||||
|
assy.solve()
|
||||||
|
show_object(assy)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Assembly colors
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Aside from RGBA values, the :class:`~cadquery.Color` class can be instantiated from a text name. Valid names are
|
||||||
|
listed along with a color sample below:
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
|
||||||
|
<div class="color-grid" style="display:grid;grid-gap:10px;grid-template-columns:repeat(auto-fill, minmax(200px,1fr));">
|
||||||
|
<div style="background-color:rgba(222,239,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">aliceblue</div>
|
||||||
|
<div style="background-color:rgba(243,211,173,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">antiquewhite</div>
|
||||||
|
<div style="background-color:rgba(255,220,180,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">antiquewhite1</div>
|
||||||
|
<div style="background-color:rgba(218,188,153,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">antiquewhite2</div>
|
||||||
|
<div style="background-color:rgba(155,134,110,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">antiquewhite3</div>
|
||||||
|
<div style="background-color:rgba(65,57,47,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">antiquewhite4</div>
|
||||||
|
<div style="background-color:rgba(54,255,167,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">aquamarine1</div>
|
||||||
|
<div style="background-color:rgba(46,218,144,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">aquamarine2</div>
|
||||||
|
<div style="background-color:rgba(15,65,44,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">aquamarine4</div>
|
||||||
|
<div style="background-color:rgba(222,255,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">azure</div>
|
||||||
|
<div style="background-color:rgba(190,218,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">azure2</div>
|
||||||
|
<div style="background-color:rgba(135,155,155,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">azure3</div>
|
||||||
|
<div style="background-color:rgba(57,65,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">azure4</div>
|
||||||
|
<div style="background-color:rgba(68,10,68,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">beet</div>
|
||||||
|
<div style="background-color:rgba(232,232,182,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">beige</div>
|
||||||
|
<div style="background-color:rgba(255,197,140,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">bisque</div>
|
||||||
|
<div style="background-color:rgba(218,169,120,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">bisque2</div>
|
||||||
|
<div style="background-color:rgba(155,120,87,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">bisque3</div>
|
||||||
|
<div style="background-color:rgba(65,52,37,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">bisque4</div>
|
||||||
|
<div style="background-color:rgba(0,0,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">black</div>
|
||||||
|
<div style="background-color:rgba(255,211,155,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">blanchedalmond</div>
|
||||||
|
<div style="background-color:rgba(0,0,255,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">blue</div>
|
||||||
|
<div style="background-color:rgba(0,0,255,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">blue1</div>
|
||||||
|
<div style="background-color:rgba(0,0,218,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">blue2</div>
|
||||||
|
<div style="background-color:rgba(0,0,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">blue3</div>
|
||||||
|
<div style="background-color:rgba(0,0,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">blue4</div>
|
||||||
|
<div style="background-color:rgba(64,6,193,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">blueviolet</div>
|
||||||
|
<div style="background-color:rgba(95,5,5,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">brown</div>
|
||||||
|
<div style="background-color:rgba(255,13,13,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">brown1</div>
|
||||||
|
<div style="background-color:rgba(218,11,11,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">brown2</div>
|
||||||
|
<div style="background-color:rgba(155,8,8,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">brown3</div>
|
||||||
|
<div style="background-color:rgba(65,4,4,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">brown4</div>
|
||||||
|
<div style="background-color:rgba(186,122,61,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">burlywood</div>
|
||||||
|
<div style="background-color:rgba(255,166,83,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">burlywood1</div>
|
||||||
|
<div style="background-color:rgba(218,142,72,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">burlywood2</div>
|
||||||
|
<div style="background-color:rgba(155,102,52,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">burlywood3</div>
|
||||||
|
<div style="background-color:rgba(65,43,23,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">burlywood4</div>
|
||||||
|
<div style="background-color:rgba(29,87,89,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">cadetblue</div>
|
||||||
|
<div style="background-color:rgba(80,232,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">cadetblue1</div>
|
||||||
|
<div style="background-color:rgba(68,199,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">cadetblue2</div>
|
||||||
|
<div style="background-color:rgba(49,142,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">cadetblue3</div>
|
||||||
|
<div style="background-color:rgba(22,60,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">cadetblue4</div>
|
||||||
|
<div style="background-color:rgba(54,255,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">chartreuse</div>
|
||||||
|
<div style="background-color:rgba(54,255,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">chartreuse1</div>
|
||||||
|
<div style="background-color:rgba(46,218,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">chartreuse2</div>
|
||||||
|
<div style="background-color:rgba(33,155,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">chartreuse3</div>
|
||||||
|
<div style="background-color:rgba(15,65,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">chartreuse4</div>
|
||||||
|
<div style="background-color:rgba(164,36,3,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">chocolate</div>
|
||||||
|
<div style="background-color:rgba(255,54,4,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">chocolate1</div>
|
||||||
|
<div style="background-color:rgba(218,46,3,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">chocolate2</div>
|
||||||
|
<div style="background-color:rgba(155,33,3,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">chocolate3</div>
|
||||||
|
<div style="background-color:rgba(65,15,1,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">chocolate4</div>
|
||||||
|
<div style="background-color:rgba(255,54,20,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">coral</div>
|
||||||
|
<div style="background-color:rgba(255,42,23,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">coral1</div>
|
||||||
|
<div style="background-color:rgba(218,36,20,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">coral2</div>
|
||||||
|
<div style="background-color:rgba(155,26,15,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">coral3</div>
|
||||||
|
<div style="background-color:rgba(65,12,7,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">coral4</div>
|
||||||
|
<div style="background-color:rgba(32,76,215,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">cornflowerblue</div>
|
||||||
|
<div style="background-color:rgba(255,239,182,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">cornsilk1</div>
|
||||||
|
<div style="background-color:rgba(218,205,155,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">cornsilk2</div>
|
||||||
|
<div style="background-color:rgba(155,147,112,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">cornsilk3</div>
|
||||||
|
<div style="background-color:rgba(65,62,47,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">cornsilk4</div>
|
||||||
|
<div style="background-color:rgba(0,255,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">cyan</div>
|
||||||
|
<div style="background-color:rgba(0,255,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">cyan1</div>
|
||||||
|
<div style="background-color:rgba(0,218,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">cyan2</div>
|
||||||
|
<div style="background-color:rgba(0,155,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">cyan3</div>
|
||||||
|
<div style="background-color:rgba(0,65,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">cyan4</div>
|
||||||
|
<div style="background-color:rgba(122,60,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkgoldenrod</div>
|
||||||
|
<div style="background-color:rgba(255,123,1,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkgoldenrod1</div>
|
||||||
|
<div style="background-color:rgba(218,106,1,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkgoldenrod2</div>
|
||||||
|
<div style="background-color:rgba(155,76,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkgoldenrod3</div>
|
||||||
|
<div style="background-color:rgba(65,33,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkgoldenrod4</div>
|
||||||
|
<div style="background-color:rgba(0,32,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkgreen</div>
|
||||||
|
<div style="background-color:rgba(129,120,37,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkkhaki</div>
|
||||||
|
<div style="background-color:rgba(23,37,7,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkolivegreen</div>
|
||||||
|
<div style="background-color:rgba(150,255,41,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">darkolivegreen1</div>
|
||||||
|
<div style="background-color:rgba(128,218,35,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkolivegreen2</div>
|
||||||
|
<div style="background-color:rgba(92,155,26,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkolivegreen3</div>
|
||||||
|
<div style="background-color:rgba(39,65,11,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkolivegreen4</div>
|
||||||
|
<div style="background-color:rgba(255,66,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkorange</div>
|
||||||
|
<div style="background-color:rgba(255,54,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkorange1</div>
|
||||||
|
<div style="background-color:rgba(218,46,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkorange2</div>
|
||||||
|
<div style="background-color:rgba(155,33,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkorange3</div>
|
||||||
|
<div style="background-color:rgba(65,15,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkorange4</div>
|
||||||
|
<div style="background-color:rgba(81,8,153,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkorchid</div>
|
||||||
|
<div style="background-color:rgba(132,12,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">darkorchid1</div>
|
||||||
|
<div style="background-color:rgba(113,10,218,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkorchid2</div>
|
||||||
|
<div style="background-color:rgba(82,8,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkorchid3</div>
|
||||||
|
<div style="background-color:rgba(35,4,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkorchid4</div>
|
||||||
|
<div style="background-color:rgba(207,77,49,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darksalmon</div>
|
||||||
|
<div style="background-color:rgba(70,128,70,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkseagreen</div>
|
||||||
|
<div style="background-color:rgba(135,255,135,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">darkseagreen1</div>
|
||||||
|
<div style="background-color:rgba(116,218,116,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">darkseagreen2</div>
|
||||||
|
<div style="background-color:rgba(83,155,83,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkseagreen3</div>
|
||||||
|
<div style="background-color:rgba(36,65,36,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkseagreen4</div>
|
||||||
|
<div style="background-color:rgba(16,11,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkslateblue</div>
|
||||||
|
<div style="background-color:rgba(7,19,19,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkslategray</div>
|
||||||
|
<div style="background-color:rgba(78,255,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">darkslategray1</div>
|
||||||
|
<div style="background-color:rgba(67,218,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">darkslategray2</div>
|
||||||
|
<div style="background-color:rgba(48,155,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkslategray3</div>
|
||||||
|
<div style="background-color:rgba(21,65,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkslategray4</div>
|
||||||
|
<div style="background-color:rgba(0,157,162,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkturquoise</div>
|
||||||
|
<div style="background-color:rgba(75,0,166,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">darkviolet</div>
|
||||||
|
<div style="background-color:rgba(255,1,74,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">deeppink</div>
|
||||||
|
<div style="background-color:rgba(218,1,63,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">deeppink2</div>
|
||||||
|
<div style="background-color:rgba(155,1,46,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">deeppink3</div>
|
||||||
|
<div style="background-color:rgba(65,0,20,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">deeppink4</div>
|
||||||
|
<div style="background-color:rgba(0,132,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">deepskyblue1</div>
|
||||||
|
<div style="background-color:rgba(0,113,218,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">deepskyblue2</div>
|
||||||
|
<div style="background-color:rgba(0,82,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">deepskyblue3</div>
|
||||||
|
<div style="background-color:rgba(0,35,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">deepskyblue4</div>
|
||||||
|
<div style="background-color:rgba(3,71,255,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">dodgerblue1</div>
|
||||||
|
<div style="background-color:rgba(2,60,218,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">dodgerblue2</div>
|
||||||
|
<div style="background-color:rgba(2,44,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">dodgerblue3</div>
|
||||||
|
<div style="background-color:rgba(1,19,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">dodgerblue4</div>
|
||||||
|
<div style="background-color:rgba(113,4,4,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">firebrick</div>
|
||||||
|
<div style="background-color:rgba(255,7,7,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">firebrick1</div>
|
||||||
|
<div style="background-color:rgba(218,6,6,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">firebrick2</div>
|
||||||
|
<div style="background-color:rgba(155,4,4,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">firebrick3</div>
|
||||||
|
<div style="background-color:rgba(65,2,2,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">firebrick4</div>
|
||||||
|
<div style="background-color:rgba(255,243,222,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">floralwhite</div>
|
||||||
|
<div style="background-color:rgba(4,65,4,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">forestgreen</div>
|
||||||
|
<div style="background-color:rgba(182,182,182,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gainsboro</div>
|
||||||
|
<div style="background-color:rgba(239,239,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">ghostwhite</div>
|
||||||
|
<div style="background-color:rgba(255,173,0,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gold</div>
|
||||||
|
<div style="background-color:rgba(255,173,0,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gold1</div>
|
||||||
|
<div style="background-color:rgba(218,148,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gold2</div>
|
||||||
|
<div style="background-color:rgba(155,106,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gold3</div>
|
||||||
|
<div style="background-color:rgba(65,45,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gold4</div>
|
||||||
|
<div style="background-color:rgba(178,95,3,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">goldenrod</div>
|
||||||
|
<div style="background-color:rgba(255,135,4,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">goldenrod1</div>
|
||||||
|
<div style="background-color:rgba(218,116,4,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">goldenrod2</div>
|
||||||
|
<div style="background-color:rgba(155,83,3,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">goldenrod3</div>
|
||||||
|
<div style="background-color:rgba(65,36,1,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">goldenrod4</div>
|
||||||
|
<div style="background-color:rgba(134,134,134,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray</div>
|
||||||
|
<div style="background-color:rgba(0,0,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray0</div>
|
||||||
|
<div style="background-color:rgba(0,0,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray1</div>
|
||||||
|
<div style="background-color:rgba(2,2,2,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray10</div>
|
||||||
|
<div style="background-color:rgba(2,2,2,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray11</div>
|
||||||
|
<div style="background-color:rgba(3,3,3,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray12</div>
|
||||||
|
<div style="background-color:rgba(3,3,3,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray13</div>
|
||||||
|
<div style="background-color:rgba(4,4,4,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray14</div>
|
||||||
|
<div style="background-color:rgba(4,4,4,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray15</div>
|
||||||
|
<div style="background-color:rgba(5,5,5,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray16</div>
|
||||||
|
<div style="background-color:rgba(6,6,6,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray17</div>
|
||||||
|
<div style="background-color:rgba(6,6,6,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray18</div>
|
||||||
|
<div style="background-color:rgba(7,7,7,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray19</div>
|
||||||
|
<div style="background-color:rgba(0,0,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray2</div>
|
||||||
|
<div style="background-color:rgba(8,8,8,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray20</div>
|
||||||
|
<div style="background-color:rgba(9,9,9,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray21</div>
|
||||||
|
<div style="background-color:rgba(10,10,10,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray22</div>
|
||||||
|
<div style="background-color:rgba(11,11,11,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray23</div>
|
||||||
|
<div style="background-color:rgba(11,11,11,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray24</div>
|
||||||
|
<div style="background-color:rgba(13,13,13,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray25</div>
|
||||||
|
<div style="background-color:rgba(13,13,13,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray26</div>
|
||||||
|
<div style="background-color:rgba(15,15,15,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray27</div>
|
||||||
|
<div style="background-color:rgba(16,16,16,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray28</div>
|
||||||
|
<div style="background-color:rgba(17,17,17,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray29</div>
|
||||||
|
<div style="background-color:rgba(0,0,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray3</div>
|
||||||
|
<div style="background-color:rgba(18,18,18,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray30</div>
|
||||||
|
<div style="background-color:rgba(19,19,19,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray31</div>
|
||||||
|
<div style="background-color:rgba(21,21,21,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray32</div>
|
||||||
|
<div style="background-color:rgba(22,22,22,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray33</div>
|
||||||
|
<div style="background-color:rgba(24,24,24,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray34</div>
|
||||||
|
<div style="background-color:rgba(25,25,25,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray35</div>
|
||||||
|
<div style="background-color:rgba(27,27,27,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray36</div>
|
||||||
|
<div style="background-color:rgba(28,28,28,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray37</div>
|
||||||
|
<div style="background-color:rgba(30,30,30,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray38</div>
|
||||||
|
<div style="background-color:rgba(31,31,31,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray39</div>
|
||||||
|
<div style="background-color:rgba(0,0,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray4</div>
|
||||||
|
<div style="background-color:rgba(33,33,33,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray40</div>
|
||||||
|
<div style="background-color:rgba(36,36,36,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray41</div>
|
||||||
|
<div style="background-color:rgba(37,37,37,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray42</div>
|
||||||
|
<div style="background-color:rgba(39,39,39,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray43</div>
|
||||||
|
<div style="background-color:rgba(41,41,41,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray44</div>
|
||||||
|
<div style="background-color:rgba(43,43,43,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray45</div>
|
||||||
|
<div style="background-color:rgba(45,45,45,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray46</div>
|
||||||
|
<div style="background-color:rgba(47,47,47,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray47</div>
|
||||||
|
<div style="background-color:rgba(49,49,49,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray48</div>
|
||||||
|
<div style="background-color:rgba(52,52,52,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray49</div>
|
||||||
|
<div style="background-color:rgba(1,1,1,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray5</div>
|
||||||
|
<div style="background-color:rgba(54,54,54,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray50</div>
|
||||||
|
<div style="background-color:rgba(56,56,56,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray51</div>
|
||||||
|
<div style="background-color:rgba(59,59,59,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray52</div>
|
||||||
|
<div style="background-color:rgba(61,61,61,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray53</div>
|
||||||
|
<div style="background-color:rgba(64,64,64,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray54</div>
|
||||||
|
<div style="background-color:rgba(66,66,66,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray55</div>
|
||||||
|
<div style="background-color:rgba(70,70,70,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray56</div>
|
||||||
|
<div style="background-color:rgba(72,72,72,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray57</div>
|
||||||
|
<div style="background-color:rgba(75,75,75,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray58</div>
|
||||||
|
<div style="background-color:rgba(77,77,77,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray59</div>
|
||||||
|
<div style="background-color:rgba(1,1,1,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray6</div>
|
||||||
|
<div style="background-color:rgba(81,81,81,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray60</div>
|
||||||
|
<div style="background-color:rgba(84,84,84,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray61</div>
|
||||||
|
<div style="background-color:rgba(87,87,87,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray62</div>
|
||||||
|
<div style="background-color:rgba(90,90,90,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray63</div>
|
||||||
|
<div style="background-color:rgba(93,93,93,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray64</div>
|
||||||
|
<div style="background-color:rgba(97,97,97,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray65</div>
|
||||||
|
<div style="background-color:rgba(99,99,99,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray66</div>
|
||||||
|
<div style="background-color:rgba(103,103,103,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray67</div>
|
||||||
|
<div style="background-color:rgba(106,106,106,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray68</div>
|
||||||
|
<div style="background-color:rgba(110,110,110,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray69</div>
|
||||||
|
<div style="background-color:rgba(1,1,1,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray7</div>
|
||||||
|
<div style="background-color:rgba(114,114,114,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray70</div>
|
||||||
|
<div style="background-color:rgba(117,117,117,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray71</div>
|
||||||
|
<div style="background-color:rgba(122,122,122,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray72</div>
|
||||||
|
<div style="background-color:rgba(125,125,125,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray73</div>
|
||||||
|
<div style="background-color:rgba(129,129,129,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray74</div>
|
||||||
|
<div style="background-color:rgba(132,132,132,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray75</div>
|
||||||
|
<div style="background-color:rgba(137,137,137,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray76</div>
|
||||||
|
<div style="background-color:rgba(140,140,140,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray77</div>
|
||||||
|
<div style="background-color:rgba(145,145,145,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray78</div>
|
||||||
|
<div style="background-color:rgba(148,148,148,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray79</div>
|
||||||
|
<div style="background-color:rgba(1,1,1,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray8</div>
|
||||||
|
<div style="background-color:rgba(153,153,153,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray80</div>
|
||||||
|
<div style="background-color:rgba(159,159,159,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray81</div>
|
||||||
|
<div style="background-color:rgba(162,162,162,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray82</div>
|
||||||
|
<div style="background-color:rgba(167,167,167,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray83</div>
|
||||||
|
<div style="background-color:rgba(176,176,176,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray85</div>
|
||||||
|
<div style="background-color:rgba(180,180,180,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray86</div>
|
||||||
|
<div style="background-color:rgba(186,186,186,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray87</div>
|
||||||
|
<div style="background-color:rgba(190,190,190,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray88</div>
|
||||||
|
<div style="background-color:rgba(195,195,195,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray89</div>
|
||||||
|
<div style="background-color:rgba(2,2,2,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">gray9</div>
|
||||||
|
<div style="background-color:rgba(199,199,199,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray90</div>
|
||||||
|
<div style="background-color:rgba(205,205,205,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray91</div>
|
||||||
|
<div style="background-color:rgba(211,211,211,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray92</div>
|
||||||
|
<div style="background-color:rgba(215,215,215,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray93</div>
|
||||||
|
<div style="background-color:rgba(222,222,222,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray94</div>
|
||||||
|
<div style="background-color:rgba(226,226,226,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray95</div>
|
||||||
|
<div style="background-color:rgba(237,237,237,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray97</div>
|
||||||
|
<div style="background-color:rgba(243,243,243,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray98</div>
|
||||||
|
<div style="background-color:rgba(248,248,248,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">gray99</div>
|
||||||
|
<div style="background-color:rgba(0,255,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">green</div>
|
||||||
|
<div style="background-color:rgba(0,255,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">green1</div>
|
||||||
|
<div style="background-color:rgba(0,218,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">green2</div>
|
||||||
|
<div style="background-color:rgba(0,155,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">green3</div>
|
||||||
|
<div style="background-color:rgba(0,65,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">green4</div>
|
||||||
|
<div style="background-color:rgba(106,255,7,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">greenyellow</div>
|
||||||
|
<div style="background-color:rgba(222,255,222,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">honeydew</div>
|
||||||
|
<div style="background-color:rgba(190,218,190,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">honeydew2</div>
|
||||||
|
<div style="background-color:rgba(135,155,135,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">honeydew3</div>
|
||||||
|
<div style="background-color:rgba(57,65,57,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">honeydew4</div>
|
||||||
|
<div style="background-color:rgba(255,36,116,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">hotpink</div>
|
||||||
|
<div style="background-color:rgba(255,39,116,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">hotpink1</div>
|
||||||
|
<div style="background-color:rgba(218,36,98,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">hotpink2</div>
|
||||||
|
<div style="background-color:rgba(155,29,71,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">hotpink3</div>
|
||||||
|
<div style="background-color:rgba(65,10,31,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">hotpink4</div>
|
||||||
|
<div style="background-color:rgba(155,27,27,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">indianred</div>
|
||||||
|
<div style="background-color:rgba(255,36,36,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">indianred1</div>
|
||||||
|
<div style="background-color:rgba(218,31,31,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">indianred2</div>
|
||||||
|
<div style="background-color:rgba(155,23,23,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">indianred3</div>
|
||||||
|
<div style="background-color:rgba(65,10,10,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">indianred4</div>
|
||||||
|
<div style="background-color:rgba(255,255,222,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">ivory</div>
|
||||||
|
<div style="background-color:rgba(218,218,190,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">ivory2</div>
|
||||||
|
<div style="background-color:rgba(155,155,135,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">ivory3</div>
|
||||||
|
<div style="background-color:rgba(65,65,57,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">ivory4</div>
|
||||||
|
<div style="background-color:rgba(222,201,66,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">khaki</div>
|
||||||
|
<div style="background-color:rgba(255,235,70,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">khaki1</div>
|
||||||
|
<div style="background-color:rgba(218,201,59,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">khaki2</div>
|
||||||
|
<div style="background-color:rgba(155,144,43,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">khaki3</div>
|
||||||
|
<div style="background-color:rgba(65,60,19,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">khaki4</div>
|
||||||
|
<div style="background-color:rgba(201,201,243,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lavender</div>
|
||||||
|
<div style="background-color:rgba(255,222,232,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lavenderblush1</div>
|
||||||
|
<div style="background-color:rgba(218,190,199,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lavenderblush2</div>
|
||||||
|
<div style="background-color:rgba(155,135,142,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lavenderblush3</div>
|
||||||
|
<div style="background-color:rgba(65,57,60,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lavenderblush4</div>
|
||||||
|
<div style="background-color:rgba(51,248,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lawngreen</div>
|
||||||
|
<div style="background-color:rgba(255,243,155,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lemonchiffon1</div>
|
||||||
|
<div style="background-color:rgba(218,207,132,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lemonchiffon2</div>
|
||||||
|
<div style="background-color:rgba(155,148,95,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lemonchiffon3</div>
|
||||||
|
<div style="background-color:rgba(65,63,41,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lemonchiffon4</div>
|
||||||
|
<div style="background-color:rgba(106,175,201,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightblue</div>
|
||||||
|
<div style="background-color:rgba(132,220,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightblue1</div>
|
||||||
|
<div style="background-color:rgba(113,188,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightblue2</div>
|
||||||
|
<div style="background-color:rgba(82,134,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightblue3</div>
|
||||||
|
<div style="background-color:rgba(35,57,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightblue4</div>
|
||||||
|
<div style="background-color:rgba(222,55,55,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightcoral</div>
|
||||||
|
<div style="background-color:rgba(190,255,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightcyan</div>
|
||||||
|
<div style="background-color:rgba(190,255,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightcyan1</div>
|
||||||
|
<div style="background-color:rgba(162,218,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightcyan2</div>
|
||||||
|
<div style="background-color:rgba(116,155,155,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightcyan3</div>
|
||||||
|
<div style="background-color:rgba(49,65,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightcyan4</div>
|
||||||
|
<div style="background-color:rgba(218,184,56,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightgoldenrod</div>
|
||||||
|
<div style="background-color:rgba(255,213,65,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightgoldenrod1</div>
|
||||||
|
<div style="background-color:rgba(218,182,56,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightgoldenrod2</div>
|
||||||
|
<div style="background-color:rgba(155,131,41,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightgoldenrod3</div>
|
||||||
|
<div style="background-color:rgba(65,55,18,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightgoldenrod4</div>
|
||||||
|
<div style="background-color:rgba(243,243,164,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightgoldenrodyellow</div>
|
||||||
|
<div style="background-color:rgba(166,166,166,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightgray</div>
|
||||||
|
<div style="background-color:rgba(255,119,135,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightpink</div>
|
||||||
|
<div style="background-color:rgba(255,107,123,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightpink1</div>
|
||||||
|
<div style="background-color:rgba(218,92,106,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightpink2</div>
|
||||||
|
<div style="background-color:rgba(155,66,76,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightpink3</div>
|
||||||
|
<div style="background-color:rgba(65,29,33,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightpink4</div>
|
||||||
|
<div style="background-color:rgba(255,89,49,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightsalmon1</div>
|
||||||
|
<div style="background-color:rgba(218,76,42,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightsalmon2</div>
|
||||||
|
<div style="background-color:rgba(155,55,31,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightsalmon3</div>
|
||||||
|
<div style="background-color:rgba(65,24,13,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightsalmon4</div>
|
||||||
|
<div style="background-color:rgba(3,113,102,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightseagreen</div>
|
||||||
|
<div style="background-color:rgba(61,157,243,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightskyblue</div>
|
||||||
|
<div style="background-color:rgba(110,193,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightskyblue1</div>
|
||||||
|
<div style="background-color:rgba(94,166,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightskyblue2</div>
|
||||||
|
<div style="background-color:rgba(67,119,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightskyblue3</div>
|
||||||
|
<div style="background-color:rgba(29,50,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightskyblue4</div>
|
||||||
|
<div style="background-color:rgba(58,41,255,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightslateblue</div>
|
||||||
|
<div style="background-color:rgba(47,62,81,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightslategray</div>
|
||||||
|
<div style="background-color:rgba(110,140,186,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightsteelblue</div>
|
||||||
|
<div style="background-color:rgba(150,192,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightsteelblue1</div>
|
||||||
|
<div style="background-color:rgba(128,164,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightsteelblue2</div>
|
||||||
|
<div style="background-color:rgba(92,117,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightsteelblue3</div>
|
||||||
|
<div style="background-color:rgba(39,50,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightsteelblue4</div>
|
||||||
|
<div style="background-color:rgba(255,255,190,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightyellow</div>
|
||||||
|
<div style="background-color:rgba(218,218,162,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightyellow2</div>
|
||||||
|
<div style="background-color:rgba(155,155,116,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">lightyellow3</div>
|
||||||
|
<div style="background-color:rgba(65,65,49,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">lightyellow4</div>
|
||||||
|
<div style="background-color:rgba(8,155,8,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">limegreen</div>
|
||||||
|
<div style="background-color:rgba(243,222,201,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">linen</div>
|
||||||
|
<div style="background-color:rgba(255,0,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">magenta</div>
|
||||||
|
<div style="background-color:rgba(255,0,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">magenta1</div>
|
||||||
|
<div style="background-color:rgba(218,0,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">magenta2</div>
|
||||||
|
<div style="background-color:rgba(155,0,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">magenta3</div>
|
||||||
|
<div style="background-color:rgba(65,0,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">magenta4</div>
|
||||||
|
<div style="background-color:rgba(110,7,29,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">maroon</div>
|
||||||
|
<div style="background-color:rgba(255,8,114,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">maroon1</div>
|
||||||
|
<div style="background-color:rgba(218,7,98,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">maroon2</div>
|
||||||
|
<div style="background-color:rgba(155,5,71,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">maroon3</div>
|
||||||
|
<div style="background-color:rgba(65,2,31,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">maroon4</div>
|
||||||
|
<div style="background-color:rgba(0,0,133,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">matrablue</div>
|
||||||
|
<div style="background-color:rgba(81,81,81,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">matragray</div>
|
||||||
|
<div style="background-color:rgba(33,155,102,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">mediumaquamarine</div>
|
||||||
|
<div style="background-color:rgba(125,23,166,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">mediumorchid</div>
|
||||||
|
<div style="background-color:rgba(190,33,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">mediumorchid1</div>
|
||||||
|
<div style="background-color:rgba(162,29,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">mediumorchid2</div>
|
||||||
|
<div style="background-color:rgba(116,21,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">mediumorchid3</div>
|
||||||
|
<div style="background-color:rgba(49,9,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">mediumorchid4</div>
|
||||||
|
<div style="background-color:rgba(74,41,180,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">mediumpurple</div>
|
||||||
|
<div style="background-color:rgba(103,56,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">mediumpurple1</div>
|
||||||
|
<div style="background-color:rgba(88,48,218,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">mediumpurple2</div>
|
||||||
|
<div style="background-color:rgba(63,35,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">mediumpurple3</div>
|
||||||
|
<div style="background-color:rgba(27,16,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">mediumpurple4</div>
|
||||||
|
<div style="background-color:rgba(11,114,42,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">mediumseagreen</div>
|
||||||
|
<div style="background-color:rgba(50,35,218,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">mediumslateblue</div>
|
||||||
|
<div style="background-color:rgba(0,243,82,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">mediumspringgreen</div>
|
||||||
|
<div style="background-color:rgba(16,162,153,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">mediumturquoise</div>
|
||||||
|
<div style="background-color:rgba(145,1,59,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">mediumvioletred</div>
|
||||||
|
<div style="background-color:rgba(2,2,41,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">midnightblue</div>
|
||||||
|
<div style="background-color:rgba(232,255,243,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">mintcream</div>
|
||||||
|
<div style="background-color:rgba(255,197,192,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">mistyrose</div>
|
||||||
|
<div style="background-color:rgba(218,169,164,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">mistyrose2</div>
|
||||||
|
<div style="background-color:rgba(155,120,117,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">mistyrose3</div>
|
||||||
|
<div style="background-color:rgba(65,52,50,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">mistyrose4</div>
|
||||||
|
<div style="background-color:rgba(255,197,117,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">moccasin</div>
|
||||||
|
<div style="background-color:rgba(255,186,106,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">navajowhite1</div>
|
||||||
|
<div style="background-color:rgba(218,159,90,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">navajowhite2</div>
|
||||||
|
<div style="background-color:rgba(155,114,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">navajowhite3</div>
|
||||||
|
<div style="background-color:rgba(65,48,28,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">navajowhite4</div>
|
||||||
|
<div style="background-color:rgba(0,0,55,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">navyblue</div>
|
||||||
|
<div style="background-color:rgba(250,232,201,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">oldlace</div>
|
||||||
|
<div style="background-color:rgba(37,68,4,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">olivedrab</div>
|
||||||
|
<div style="background-color:rgba(134,255,12,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">olivedrab1</div>
|
||||||
|
<div style="background-color:rgba(114,218,10,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">olivedrab2</div>
|
||||||
|
<div style="background-color:rgba(82,155,8,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">olivedrab3</div>
|
||||||
|
<div style="background-color:rgba(36,65,4,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">olivedrab4</div>
|
||||||
|
<div style="background-color:rgba(255,95,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">orange</div>
|
||||||
|
<div style="background-color:rgba(255,95,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">orange1</div>
|
||||||
|
<div style="background-color:rgba(218,82,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">orange2</div>
|
||||||
|
<div style="background-color:rgba(155,59,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">orange3</div>
|
||||||
|
<div style="background-color:rgba(65,26,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">orange4</div>
|
||||||
|
<div style="background-color:rgba(255,15,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">orangered</div>
|
||||||
|
<div style="background-color:rgba(255,15,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">orangered1</div>
|
||||||
|
<div style="background-color:rgba(218,13,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">orangered2</div>
|
||||||
|
<div style="background-color:rgba(155,9,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">orangered3</div>
|
||||||
|
<div style="background-color:rgba(65,4,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">orangered4</div>
|
||||||
|
<div style="background-color:rgba(178,41,171,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">orchid</div>
|
||||||
|
<div style="background-color:rgba(255,57,243,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">orchid1</div>
|
||||||
|
<div style="background-color:rgba(218,49,207,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">orchid2</div>
|
||||||
|
<div style="background-color:rgba(155,36,148,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">orchid3</div>
|
||||||
|
<div style="background-color:rgba(65,16,63,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">orchid4</div>
|
||||||
|
<div style="background-color:rgba(218,205,102,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">palegoldenrod</div>
|
||||||
|
<div style="background-color:rgba(80,245,80,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">palegreen</div>
|
||||||
|
<div style="background-color:rgba(82,255,82,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">palegreen1</div>
|
||||||
|
<div style="background-color:rgba(71,218,71,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">palegreen2</div>
|
||||||
|
<div style="background-color:rgba(51,155,51,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">palegreen3</div>
|
||||||
|
<div style="background-color:rgba(22,65,22,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">palegreen4</div>
|
||||||
|
<div style="background-color:rgba(109,218,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">paleturquoise</div>
|
||||||
|
<div style="background-color:rgba(126,255,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">paleturquoise1</div>
|
||||||
|
<div style="background-color:rgba(107,218,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">paleturquoise2</div>
|
||||||
|
<div style="background-color:rgba(77,155,155,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">paleturquoise3</div>
|
||||||
|
<div style="background-color:rgba(33,65,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">paleturquoise4</div>
|
||||||
|
<div style="background-color:rgba(180,41,74,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">palevioletred</div>
|
||||||
|
<div style="background-color:rgba(255,56,103,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">palevioletred1</div>
|
||||||
|
<div style="background-color:rgba(218,48,88,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">palevioletred2</div>
|
||||||
|
<div style="background-color:rgba(155,35,63,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">palevioletred3</div>
|
||||||
|
<div style="background-color:rgba(65,16,27,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">palevioletred4</div>
|
||||||
|
<div style="background-color:rgba(255,220,169,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">papayawhip</div>
|
||||||
|
<div style="background-color:rgba(255,178,123,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">peachpuff</div>
|
||||||
|
<div style="background-color:rgba(218,152,106,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">peachpuff2</div>
|
||||||
|
<div style="background-color:rgba(155,109,76,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">peachpuff3</div>
|
||||||
|
<div style="background-color:rgba(65,47,33,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">peachpuff4</div>
|
||||||
|
<div style="background-color:rgba(155,59,12,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">peru</div>
|
||||||
|
<div style="background-color:rgba(255,134,152,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">pink</div>
|
||||||
|
<div style="background-color:rgba(255,117,142,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">pink1</div>
|
||||||
|
<div style="background-color:rgba(218,101,122,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">pink2</div>
|
||||||
|
<div style="background-color:rgba(155,72,87,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">pink3</div>
|
||||||
|
<div style="background-color:rgba(65,31,38,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">pink4</div>
|
||||||
|
<div style="background-color:rgba(184,89,184,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">plum</div>
|
||||||
|
<div style="background-color:rgba(255,126,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">plum1</div>
|
||||||
|
<div style="background-color:rgba(218,107,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">plum2</div>
|
||||||
|
<div style="background-color:rgba(155,77,155,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">plum3</div>
|
||||||
|
<div style="background-color:rgba(65,33,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">plum4</div>
|
||||||
|
<div style="background-color:rgba(110,190,201,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">powderblue</div>
|
||||||
|
<div style="background-color:rgba(89,3,222,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">purple</div>
|
||||||
|
<div style="background-color:rgba(83,7,255,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">purple1</div>
|
||||||
|
<div style="background-color:rgba(72,6,218,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">purple2</div>
|
||||||
|
<div style="background-color:rgba(52,4,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">purple3</div>
|
||||||
|
<div style="background-color:rgba(23,2,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">purple4</div>
|
||||||
|
<div style="background-color:rgba(255,0,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">red</div>
|
||||||
|
<div style="background-color:rgba(255,0,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">red1</div>
|
||||||
|
<div style="background-color:rgba(218,0,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">red2</div>
|
||||||
|
<div style="background-color:rgba(155,0,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">red3</div>
|
||||||
|
<div style="background-color:rgba(65,0,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">red4</div>
|
||||||
|
<div style="background-color:rgba(128,70,70,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">rosybrown</div>
|
||||||
|
<div style="background-color:rgba(255,135,135,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">rosybrown1</div>
|
||||||
|
<div style="background-color:rgba(218,116,116,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">rosybrown2</div>
|
||||||
|
<div style="background-color:rgba(155,83,83,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">rosybrown3</div>
|
||||||
|
<div style="background-color:rgba(65,36,36,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">rosybrown4</div>
|
||||||
|
<div style="background-color:rgba(13,36,192,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">royalblue</div>
|
||||||
|
<div style="background-color:rgba(16,46,255,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">royalblue1</div>
|
||||||
|
<div style="background-color:rgba(14,39,218,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">royalblue2</div>
|
||||||
|
<div style="background-color:rgba(10,29,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">royalblue3</div>
|
||||||
|
<div style="background-color:rgba(5,13,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">royalblue4</div>
|
||||||
|
<div style="background-color:rgba(65,15,1,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">saddlebrown</div>
|
||||||
|
<div style="background-color:rgba(243,55,42,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">salmon</div>
|
||||||
|
<div style="background-color:rgba(255,66,36,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">salmon1</div>
|
||||||
|
<div style="background-color:rgba(218,56,31,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">salmon2</div>
|
||||||
|
<div style="background-color:rgba(155,41,22,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">salmon3</div>
|
||||||
|
<div style="background-color:rgba(65,18,10,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">salmon4</div>
|
||||||
|
<div style="background-color:rgba(230,94,29,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">sandybrown</div>
|
||||||
|
<div style="background-color:rgba(6,65,24,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">seagreen</div>
|
||||||
|
<div style="background-color:rgba(22,255,88,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">seagreen1</div>
|
||||||
|
<div style="background-color:rgba(19,218,75,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">seagreen2</div>
|
||||||
|
<div style="background-color:rgba(14,155,55,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">seagreen3</div>
|
||||||
|
<div style="background-color:rgba(6,65,24,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">seagreen4</div>
|
||||||
|
<div style="background-color:rgba(255,232,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">seashell</div>
|
||||||
|
<div style="background-color:rgba(218,199,186,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">seashell2</div>
|
||||||
|
<div style="background-color:rgba(155,142,132,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">seashell3</div>
|
||||||
|
<div style="background-color:rgba(65,60,56,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">seashell4</div>
|
||||||
|
<div style="background-color:rgba(89,21,6,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">sienna</div>
|
||||||
|
<div style="background-color:rgba(255,56,16,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">sienna1</div>
|
||||||
|
<div style="background-color:rgba(218,48,13,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">sienna2</div>
|
||||||
|
<div style="background-color:rgba(155,35,10,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">sienna3</div>
|
||||||
|
<div style="background-color:rgba(65,16,4,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">sienna4</div>
|
||||||
|
<div style="background-color:rgba(61,157,211,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">skyblue</div>
|
||||||
|
<div style="background-color:rgba(61,157,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">skyblue1</div>
|
||||||
|
<div style="background-color:rgba(53,134,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">skyblue2</div>
|
||||||
|
<div style="background-color:rgba(38,97,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">skyblue3</div>
|
||||||
|
<div style="background-color:rgba(17,41,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">skyblue4</div>
|
||||||
|
<div style="background-color:rgba(36,26,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">slateblue</div>
|
||||||
|
<div style="background-color:rgba(57,40,255,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">slateblue1</div>
|
||||||
|
<div style="background-color:rgba(49,34,218,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">slateblue2</div>
|
||||||
|
<div style="background-color:rgba(36,25,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">slateblue3</div>
|
||||||
|
<div style="background-color:rgba(16,11,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">slateblue4</div>
|
||||||
|
<div style="background-color:rgba(41,55,71,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">slategray</div>
|
||||||
|
<div style="background-color:rgba(144,193,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">slategray1</div>
|
||||||
|
<div style="background-color:rgba(123,166,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">slategray2</div>
|
||||||
|
<div style="background-color:rgba(88,119,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">slategray3</div>
|
||||||
|
<div style="background-color:rgba(38,50,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">slategray4</div>
|
||||||
|
<div style="background-color:rgba(255,243,243,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">snow</div>
|
||||||
|
<div style="background-color:rgba(218,207,207,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">snow2</div>
|
||||||
|
<div style="background-color:rgba(155,148,148,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">snow3</div>
|
||||||
|
<div style="background-color:rgba(65,63,63,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">snow4</div>
|
||||||
|
<div style="background-color:rgba(0,255,54,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">springgreen</div>
|
||||||
|
<div style="background-color:rgba(0,218,46,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">springgreen2</div>
|
||||||
|
<div style="background-color:rgba(0,155,33,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">springgreen3</div>
|
||||||
|
<div style="background-color:rgba(0,65,15,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">springgreen4</div>
|
||||||
|
<div style="background-color:rgba(15,56,116,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">steelblue</div>
|
||||||
|
<div style="background-color:rgba(31,122,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">steelblue1</div>
|
||||||
|
<div style="background-color:rgba(27,105,218,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">steelblue2</div>
|
||||||
|
<div style="background-color:rgba(19,75,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">steelblue3</div>
|
||||||
|
<div style="background-color:rgba(9,32,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">steelblue4</div>
|
||||||
|
<div style="background-color:rgba(164,116,66,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">tan</div>
|
||||||
|
<div style="background-color:rgba(255,95,19,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">tan1</div>
|
||||||
|
<div style="background-color:rgba(218,82,16,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">tan2</div>
|
||||||
|
<div style="background-color:rgba(155,59,12,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">tan3</div>
|
||||||
|
<div style="background-color:rgba(65,26,6,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">tan4</div>
|
||||||
|
<div style="background-color:rgba(10,68,68,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">teal</div>
|
||||||
|
<div style="background-color:rgba(175,132,175,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">thistle</div>
|
||||||
|
<div style="background-color:rgba(255,192,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">thistle1</div>
|
||||||
|
<div style="background-color:rgba(218,164,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">thistle2</div>
|
||||||
|
<div style="background-color:rgba(155,117,155,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">thistle3</div>
|
||||||
|
<div style="background-color:rgba(65,50,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">thistle4</div>
|
||||||
|
<div style="background-color:rgba(255,31,16,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">tomato</div>
|
||||||
|
<div style="background-color:rgba(255,31,16,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">tomato1</div>
|
||||||
|
<div style="background-color:rgba(218,27,13,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">tomato2</div>
|
||||||
|
<div style="background-color:rgba(155,19,10,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">tomato3</div>
|
||||||
|
<div style="background-color:rgba(65,9,4,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">tomato4</div>
|
||||||
|
<div style="background-color:rgba(13,190,160,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">turquoise</div>
|
||||||
|
<div style="background-color:rgba(0,232,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">turquoise1</div>
|
||||||
|
<div style="background-color:rgba(0,199,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">turquoise2</div>
|
||||||
|
<div style="background-color:rgba(0,142,155,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">turquoise3</div>
|
||||||
|
<div style="background-color:rgba(0,60,65,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">turquoise4</div>
|
||||||
|
<div style="background-color:rgba(218,56,218,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">violet</div>
|
||||||
|
<div style="background-color:rgba(160,3,71,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">violetred</div>
|
||||||
|
<div style="background-color:rgba(255,12,77,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">violetred1</div>
|
||||||
|
<div style="background-color:rgba(218,10,66,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">violetred2</div>
|
||||||
|
<div style="background-color:rgba(155,8,47,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">violetred3</div>
|
||||||
|
<div style="background-color:rgba(65,4,21,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">violetred4</div>
|
||||||
|
<div style="background-color:rgba(232,186,114,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">wheat</div>
|
||||||
|
<div style="background-color:rgba(255,203,125,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">wheat1</div>
|
||||||
|
<div style="background-color:rgba(218,175,107,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">wheat2</div>
|
||||||
|
<div style="background-color:rgba(155,125,77,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">wheat3</div>
|
||||||
|
<div style="background-color:rgba(65,53,33,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">wheat4</div>
|
||||||
|
<div style="background-color:rgba(255,255,255,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">white</div>
|
||||||
|
<div style="background-color:rgba(232,232,232,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">whitesmoke</div>
|
||||||
|
<div style="background-color:rgba(255,255,0,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">yellow</div>
|
||||||
|
<div style="background-color:rgba(255,255,0,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">yellow1</div>
|
||||||
|
<div style="background-color:rgba(218,218,0,1.0);padding:10px;border-radius:5px;color:rgba(0,0,0);">yellow2</div>
|
||||||
|
<div style="background-color:rgba(155,155,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">yellow3</div>
|
||||||
|
<div style="background-color:rgba(65,65,0,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">yellow4</div>
|
||||||
|
<div style="background-color:rgba(82,155,8,1.0);padding:10px;border-radius:5px;color:rgba(255,255,255);">yellowgreen</div>
|
||||||
|
</div>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
CadQuery Class Summary
|
CadQuery Class Summary
|
||||||
*************************
|
*************************
|
||||||
|
|
||||||
This page documents all of the methods and functions of the CadQuery classes, organized alphabatically.
|
This page documents all of the methods and functions of the CadQuery classes, organized alphabetically.
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ extensions = [
|
|||||||
"sphinx.ext.viewcode",
|
"sphinx.ext.viewcode",
|
||||||
"sphinx.ext.autosummary",
|
"sphinx.ext.autosummary",
|
||||||
"cadquery.cq_directive",
|
"cadquery.cq_directive",
|
||||||
|
"sphinx.ext.mathjax",
|
||||||
]
|
]
|
||||||
|
|
||||||
always_document_param_types = True
|
always_document_param_types = True
|
||||||
|
@ -59,7 +59,9 @@ Plate with Hole
|
|||||||
A rectangular box, but with a hole added.
|
A rectangular box, but with a hole added.
|
||||||
|
|
||||||
"\>Z" selects the top most face of the resulting box. The hole is located in the center because the default origin
|
"\>Z" selects the top most face of the resulting box. The hole is located in the center because the default origin
|
||||||
of a working plane is at the center of the face. The default hole depth is through the entire part.
|
of a working plane is the projected origin of the last Workplane, the last Workplane having origin at (0,0,0) the
|
||||||
|
projection is at the center of the face. The default hole depth is through the entire part.
|
||||||
|
|
||||||
|
|
||||||
.. cadquery::
|
.. cadquery::
|
||||||
|
|
||||||
@ -110,9 +112,9 @@ Building Profiles using lines and arcs
|
|||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
Sometimes you need to build complex profiles using lines and arcs. This example builds a prismatic
|
Sometimes you need to build complex profiles using lines and arcs. This example builds a prismatic
|
||||||
solid from 2-d operations.
|
solid from 2D operations.
|
||||||
|
|
||||||
2-d operations maintain a current point, which is initially at the origin. Use close() to finish a
|
2D operations maintain a current point, which is initially at the origin. Use close() to finish a
|
||||||
closed curve.
|
closed curve.
|
||||||
|
|
||||||
|
|
||||||
@ -193,7 +195,7 @@ like :py:meth:`Workplane.circle` and :py:meth:`Workplane.rect`, will operate on
|
|||||||
Polygons
|
Polygons
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
You can create polygons for each stack point if you would like. Useful in 3d printers whos firmware does not
|
You can create polygons for each stack point if you would like. Useful in 3d printers whose firmware does not
|
||||||
correct for small hole sizes.
|
correct for small hole sizes.
|
||||||
|
|
||||||
.. cadquery::
|
.. cadquery::
|
||||||
@ -279,7 +281,7 @@ needs a complex profile
|
|||||||
Mirroring Symmetric Geometry
|
Mirroring Symmetric Geometry
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
You can mirror 2-d geometry when your shape is symmetric. In this example we also
|
You can mirror 2D geometry when your shape is symmetric. In this example we also
|
||||||
introduce horizontal and vertical lines, which make for slightly easier coding.
|
introduce horizontal and vertical lines, which make for slightly easier coding.
|
||||||
|
|
||||||
|
|
||||||
@ -739,7 +741,7 @@ Here we fillet all of the edges of a simple plate.
|
|||||||
Tagging objects
|
Tagging objects
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
The :py:meth:`Workplane.tag` method can be used to tag a particular object in the chain with a string, so that it can be refered to later in the chain.
|
The :py:meth:`Workplane.tag` method can be used to tag a particular object in the chain with a string, so that it can be referred to later in the chain.
|
||||||
|
|
||||||
The :py:meth:`Workplane.workplaneFromTagged` method applies :py:meth:`Workplane.copyWorkplane` to a tagged object. For example, when extruding two different solids from a surface, after the first solid is extruded it can become difficult to reselect the original surface with CadQuery's other selectors.
|
The :py:meth:`Workplane.workplaneFromTagged` method applies :py:meth:`Workplane.copyWorkplane` to a tagged object. For example, when extruding two different solids from a surface, after the first solid is extruded it can become difficult to reselect the original surface with CadQuery's other selectors.
|
||||||
|
|
||||||
@ -845,10 +847,10 @@ ones at 13 lines, but that's very short compared to the pythonOCC version, which
|
|||||||
.threePointArc((L/2.0, w/2.0 + t), (L, w/2.0)).vLine(-w/2.0)
|
.threePointArc((L/2.0, w/2.0 + t), (L, w/2.0)).vLine(-w/2.0)
|
||||||
.mirrorX().extrude(30.0, True))
|
.mirrorX().extrude(30.0, True))
|
||||||
|
|
||||||
#make the neck
|
# Make the neck
|
||||||
p = p.faces(">Z").workplane(centerOption="CenterOfMass").circle(3.0).extrude(2.0, True)
|
p = p.faces(">Z").workplane(centerOption="CenterOfMass").circle(3.0).extrude(2.0, True)
|
||||||
|
|
||||||
#make a shell
|
# Make a shell
|
||||||
result = p.faces(">Z").shell(0.3)
|
result = p.faces(">Z").shell(0.3)
|
||||||
|
|
||||||
.. topic:: Api References
|
.. topic:: Api References
|
||||||
@ -919,7 +921,7 @@ A Parametric Enclosure
|
|||||||
box = (box.faces(">Z").workplane(-p_thickness)
|
box = (box.faces(">Z").workplane(-p_thickness)
|
||||||
.rect(POSTWIDTH, POSTLENGTH, forConstruction=True)
|
.rect(POSTWIDTH, POSTLENGTH, forConstruction=True)
|
||||||
.vertices().circle(p_screwpostOD/2.0).circle(p_screwpostID/2.0)
|
.vertices().circle(p_screwpostOD/2.0).circle(p_screwpostID/2.0)
|
||||||
.extrude((-1.0)*(p_outerHeight + p_lipHeight -p_thickness ),True))
|
.extrude(-1.0*(p_outerHeight + p_lipHeight - p_thickness),True))
|
||||||
|
|
||||||
# split lid into top and bottom parts
|
# split lid into top and bottom parts
|
||||||
(lid, bottom) = box.faces(">Z").workplane(-p_thickness - p_lipHeight).split(keepTop=True, keepBottom=True).all() # splits into two solids
|
(lid, bottom) = box.faces(">Z").workplane(-p_thickness - p_lipHeight).split(keepTop=True, keepBottom=True).all() # splits into two solids
|
||||||
@ -933,11 +935,11 @@ A Parametric Enclosure
|
|||||||
|
|
||||||
# add holes of the desired type
|
# add holes of the desired type
|
||||||
if p_boreDiameter > 0 and p_boreDepth > 0:
|
if p_boreDiameter > 0 and p_boreDepth > 0:
|
||||||
topOfLid = topOfLidCenters.cboreHole(p_screwpostID,p_boreDiameter,p_boreDepth,(2.0)*p_thickness)
|
topOfLid = topOfLidCenters.cboreHole(p_screwpostID, p_boreDiameter, p_boreDepth, 2.0*p_thickness)
|
||||||
elif p_countersinkDiameter > 0 and p_countersinkAngle > 0:
|
elif p_countersinkDiameter > 0 and p_countersinkAngle > 0:
|
||||||
topOfLid = topOfLidCenters.cskHole(p_screwpostID,p_countersinkDiameter,p_countersinkAngle,(2.0)*p_thickness)
|
topOfLid = topOfLidCenters.cskHole(p_screwpostID, p_countersinkDiameter, p_countersinkAngle, 2.0*p_thickness)
|
||||||
else:
|
else:
|
||||||
topOfLid= topOfLidCenters.hole(p_screwpostID,(2.0)*p_thickness)
|
topOfLid = topOfLidCenters.hole(p_screwpostID, 2.0*p_thickness)
|
||||||
|
|
||||||
# flip lid upside down if desired
|
# flip lid upside down if desired
|
||||||
if p_flipLid:
|
if p_flipLid:
|
||||||
|
@ -103,7 +103,7 @@ are designed to aid in plugin creation:
|
|||||||
|
|
||||||
* :py:meth:`cadquery.Workplane.wire` gathers up all of the edges that have been drawn ( eg, by line, vline, etc ), and
|
* :py:meth:`cadquery.Workplane.wire` gathers up all of the edges that have been drawn ( eg, by line, vline, etc ), and
|
||||||
attempts to combine them into a single wire, which is returned. This should be used when your plugin creates
|
attempts to combine them into a single wire, which is returned. This should be used when your plugin creates
|
||||||
2-d edges, and you know it is time to collect them into a single wire.
|
2D edges, and you know it is time to collect them into a single wire.
|
||||||
|
|
||||||
* :py:meth:`cadquery.Workplane.plane` provides a reference to the workplane, which allows you to convert between workplane
|
* :py:meth:`cadquery.Workplane.plane` provides a reference to the workplane, which allows you to convert between workplane
|
||||||
coordinates and global coordinates:
|
coordinates and global coordinates:
|
||||||
|
74
doc/gen_colors.py
Normal file
74
doc/gen_colors.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
"""
|
||||||
|
A script to generate RST (HTML only) for displaying all the colours supported
|
||||||
|
by OCP. Used in the file assy.rst.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from OCP import Quantity
|
||||||
|
import cadquery as cq
|
||||||
|
from typing import Dict
|
||||||
|
from itertools import chain
|
||||||
|
|
||||||
|
|
||||||
|
OCP_COLOR_LEADER, SEP = "Quantity_NOC", "_"
|
||||||
|
|
||||||
|
TEMPLATE = """\
|
||||||
|
<div style="background-color:rgba({background_color});padding:10px;border-radius:5px;color:rgba({text_color});">{color_name}</div>\
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def color_to_rgba_str(c: cq.Color) -> str:
|
||||||
|
""" Convert a Color object to a string for the HTML/CSS template.
|
||||||
|
"""
|
||||||
|
t = c.toTuple()
|
||||||
|
vals = [int(v * 255) for v in t[:3]]
|
||||||
|
return ",".join([str(v) for v in chain(vals, [t[3]])])
|
||||||
|
|
||||||
|
|
||||||
|
def calc_text_color(c: cq.Color) -> str:
|
||||||
|
""" Calculate required overlay text color from background color.
|
||||||
|
"""
|
||||||
|
val = sum(c.toTuple()[:3]) / 3
|
||||||
|
if val < 0.5:
|
||||||
|
rv = "255,255,255"
|
||||||
|
else:
|
||||||
|
rv = "0,0,0"
|
||||||
|
|
||||||
|
return rv
|
||||||
|
|
||||||
|
|
||||||
|
def get_colors() -> Dict[str, cq.Color]:
|
||||||
|
""" Scan OCP for colors and output to a dict.
|
||||||
|
"""
|
||||||
|
colors = {}
|
||||||
|
for name in dir(Quantity):
|
||||||
|
splitted = name.rsplit(SEP, 1)
|
||||||
|
if splitted[0] == OCP_COLOR_LEADER:
|
||||||
|
colors.update({splitted[1].lower(): cq.Color(splitted[1])})
|
||||||
|
|
||||||
|
return colors
|
||||||
|
|
||||||
|
|
||||||
|
def rst():
|
||||||
|
""" Produce the text for a Sphinx directive.
|
||||||
|
"""
|
||||||
|
lines = [
|
||||||
|
".. raw:: html",
|
||||||
|
"",
|
||||||
|
' <div class="color-grid" style="display:grid;grid-gap:10px;grid-template-columns:repeat(auto-fill, minmax(200px,1fr));">',
|
||||||
|
]
|
||||||
|
colors = get_colors()
|
||||||
|
for name, c in colors.items():
|
||||||
|
lines += [
|
||||||
|
TEMPLATE.format(
|
||||||
|
background_color=color_to_rgba_str(c),
|
||||||
|
text_color=calc_text_color(c),
|
||||||
|
color_name=name,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
lines.append(" </div>")
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(rst())
|
@ -19,7 +19,7 @@ CadQuery is an intuitive, easy-to-use Python library for building parametric 3D
|
|||||||
* Provide a non-proprietary, plain text model format that can be edited and executed with only a web browser
|
* Provide a non-proprietary, plain text model format that can be edited and executed with only a web browser
|
||||||
|
|
||||||
CadQuery 2 is based on
|
CadQuery 2 is based on
|
||||||
`OCP https://github.com/CadQuery/OCP`_,
|
`OCP <https://github.com/CadQuery/OCP>`_,
|
||||||
which is a set of Python bindings for the open-source `OpenCascade <http://www.opencascade.com/>`_ modelling kernel.
|
which is a set of Python bindings for the open-source `OpenCascade <http://www.opencascade.com/>`_ modelling kernel.
|
||||||
|
|
||||||
Using CadQuery, you can build fully parametric models with a very small amount of code. For example, this simple script
|
Using CadQuery, you can build fully parametric models with a very small amount of code. For example, this simple script
|
||||||
@ -81,9 +81,9 @@ Where does the name CadQuery come from?
|
|||||||
========================================
|
========================================
|
||||||
|
|
||||||
CadQuery is inspired by `jQuery <http://www.jquery.com>`_, a popular framework that
|
CadQuery is inspired by `jQuery <http://www.jquery.com>`_, a popular framework that
|
||||||
revolutionized web development involving javascript.
|
revolutionized web development involving JavaScript.
|
||||||
|
|
||||||
CadQuery is for 3D CAD what jQuery is for javascript.
|
CadQuery is for 3D CAD what jQuery is for JavaScript.
|
||||||
If you are familiar with how jQuery works, you will probably recognize several jQuery features that CadQuery uses:
|
If you are familiar with how jQuery works, you will probably recognize several jQuery features that CadQuery uses:
|
||||||
|
|
||||||
* A fluent API to create clean, easy to read code
|
* A fluent API to create clean, easy to read code
|
||||||
|
@ -90,7 +90,7 @@ You can select Vertices, Edges, Faces, Solids, and Wires using selectors.
|
|||||||
|
|
||||||
Think of selectors as the equivalent of your hand and mouse, if you were to build an object using a conventional CAD system.
|
Think of selectors as the equivalent of your hand and mouse, if you were to build an object using a conventional CAD system.
|
||||||
|
|
||||||
You can learn more about selectors :ref:`selectors`
|
See :ref:`selectors` to learn more.
|
||||||
|
|
||||||
|
|
||||||
Construction Geometry
|
Construction Geometry
|
||||||
@ -99,7 +99,7 @@ Construction geometry are features that are not part of the object, but are only
|
|||||||
A common example might be to define a rectangle, and then use the corners to define the location of a set of holes.
|
A common example might be to define a rectangle, and then use the corners to define the location of a set of holes.
|
||||||
|
|
||||||
Most CadQuery construction methods provide a ``forConstruction`` keyword, which creates a feature that will only be used
|
Most CadQuery construction methods provide a ``forConstruction`` keyword, which creates a feature that will only be used
|
||||||
to locate other features
|
to locate other features.
|
||||||
|
|
||||||
|
|
||||||
The Stack
|
The Stack
|
||||||
@ -295,7 +295,7 @@ Which produces the output:
|
|||||||
The first thing to note is that this is a different :class:`~cadquery.Workplane` object to the
|
The first thing to note is that this is a different :class:`~cadquery.Workplane` object to the
|
||||||
previous one, and in the :attr:`~cadquery.Workplane.parent` attribute of this
|
previous one, and in the :attr:`~cadquery.Workplane.parent` attribute of this
|
||||||
:class:`~cadquery.Workplane` is our previous :class:`~cadquery.Workplane`. Returning a new instance
|
:class:`~cadquery.Workplane` is our previous :class:`~cadquery.Workplane`. Returning a new instance
|
||||||
of :class:`~caduqery.Workplane` is the normal behaviour of most :class:`~cadquery.Workplane` methods
|
of :class:`~cadquery.Workplane` is the normal behaviour of most :class:`~cadquery.Workplane` methods
|
||||||
(with some exceptions, as will be shown below) and this is how the `chaining`_ concept is
|
(with some exceptions, as will be shown below) and this is how the `chaining`_ concept is
|
||||||
implemented.
|
implemented.
|
||||||
|
|
||||||
@ -387,7 +387,7 @@ The output is now:
|
|||||||
tags: {'base': <cadquery.cq.Workplane object at 0xaa90>}
|
tags: {'base': <cadquery.cq.Workplane object at 0xaa90>}
|
||||||
|
|
||||||
Modelling operations take their wires and edges from the modelling context's pending lists. In order
|
Modelling operations take their wires and edges from the modelling context's pending lists. In order
|
||||||
to use the :meth:`~cadquery.Workplane.loft` command futher down the chain, we need to push this wire
|
to use the :meth:`~cadquery.Workplane.loft` command further down the chain, we need to push this wire
|
||||||
to the modelling context with::
|
to the modelling context with::
|
||||||
|
|
||||||
part = part.toPending()
|
part = part.toPending()
|
||||||
@ -560,14 +560,14 @@ another :class:`~cadquery.Workplane` method).
|
|||||||
|
|
||||||
The next step is to extrude this circle and create a cylindrical protrusion::
|
The next step is to extrude this circle and create a cylindrical protrusion::
|
||||||
|
|
||||||
part = part.extrude(1)
|
part = part.extrude(1, clean=False)
|
||||||
|
|
||||||
Now:
|
Now:
|
||||||
|
|
||||||
.. code-block:: none
|
.. code-block:: none
|
||||||
|
|
||||||
Workplane object at 0xafd0:
|
Workplane object at 0xafd0:
|
||||||
parent: Workplane object at 0x6df0
|
parent: Workplane object at 0xe790
|
||||||
plane: Plane object at 0x3e80:
|
plane: Plane object at 0x3e80:
|
||||||
origin: (0.5, 0.0, 0.0)
|
origin: (0.5, 0.0, 0.0)
|
||||||
z direction: (1.0, 0.0, 0.0)
|
z direction: (1.0, 0.0, 0.0)
|
||||||
@ -582,6 +582,16 @@ The :meth:`~cadquery.Workplane.extrude` method has cleared all the pending wires
|
|||||||
that is shown in the 3D view above.
|
that is shown in the 3D view above.
|
||||||
|
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
The :meth:`~cadquery.Workplane.extrude` has an argument for ``clean`` which defaults to ``True``.
|
||||||
|
This extrudes the pending wires (creating a new :class:`~cadquery.Workplane` object), then runs
|
||||||
|
the :meth:`~cadquery.Workplane.clean` method to refine the result, creating another
|
||||||
|
:class:`~cadquery.Workplane`. If you were to run the example with the default
|
||||||
|
``clean=True`` then you would see an intermediate
|
||||||
|
:class:`~cadquery.Workplane` object in :attr:`~cadquery.Workplane.parent`
|
||||||
|
rather than the object from the previous step.
|
||||||
|
|
||||||
|
|
||||||
Assemblies
|
Assemblies
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ There are a couple of things to note about this line:
|
|||||||
1. The :py:meth:`cadquery.Workplane.rect` function draws a rectangle. **forConstruction=True**
|
1. The :py:meth:`cadquery.Workplane.rect` function draws a rectangle. **forConstruction=True**
|
||||||
tells CadQuery that this rectangle will not form a part of the solid,
|
tells CadQuery that this rectangle will not form a part of the solid,
|
||||||
but we are just using it to help define some other geometry.
|
but we are just using it to help define some other geometry.
|
||||||
2. Unless you specifiy otherwise, a rectangle is drawn with its center on the current workplane center-- in
|
2. Unless you specify otherwise, a rectangle is drawn with its center on the current workplane center-- in
|
||||||
this case, the center of the top face of the block. So this rectangle will be centered on the face.
|
this case, the center of the top face of the block. So this rectangle will be centered on the face.
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ implement more constraints
|
|||||||
in plane, on axis, parallel to vector
|
in plane, on axis, parallel to vector
|
||||||
|
|
||||||
|
|
||||||
2-d operations
|
2D operations
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
arc construction using relative measures
|
arc construction using relative measures
|
||||||
@ -47,10 +47,10 @@ trimming
|
|||||||
construction lines
|
construction lines
|
||||||
especially centerlines
|
especially centerlines
|
||||||
|
|
||||||
2-d fillets
|
2D fillets
|
||||||
for a rectangle, or for consecutive selected lines
|
for a rectangle, or for consecutive selected lines
|
||||||
|
|
||||||
2-d chamfers
|
2D chamfers
|
||||||
based on rectangles, polygons, polylines, or adjacent selected lines
|
based on rectangles, polygons, polylines, or adjacent selected lines
|
||||||
|
|
||||||
mirror around centerline
|
mirror around centerline
|
||||||
@ -72,7 +72,7 @@ feature snap
|
|||||||
polyline edges
|
polyline edges
|
||||||
allow polyline to be combined with other edges/curves
|
allow polyline to be combined with other edges/curves
|
||||||
|
|
||||||
3-d operations
|
3D operations
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
rotation/transform that return a copy
|
rotation/transform that return a copy
|
||||||
@ -81,7 +81,6 @@ rotation/transform that return a copy
|
|||||||
primitive creation
|
primitive creation
|
||||||
Need primitive creation for:
|
Need primitive creation for:
|
||||||
* cone
|
* cone
|
||||||
* cylinder
|
|
||||||
* torus
|
* torus
|
||||||
* wedge
|
* wedge
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ defaultSweep = (
|
|||||||
.sweep(path, multisection=True)
|
.sweep(path, multisection=True)
|
||||||
)
|
)
|
||||||
|
|
||||||
# We can sweep thrue different shapes
|
# We can sweep through different shapes
|
||||||
recttocircleSweep = (
|
recttocircleSweep = (
|
||||||
cq.Workplane("YZ")
|
cq.Workplane("YZ")
|
||||||
.workplane(offset=-10.0)
|
.workplane(offset=-10.0)
|
||||||
@ -63,7 +63,7 @@ path = (
|
|||||||
|
|
||||||
# Placement of different shapes should follow the path
|
# Placement of different shapes should follow the path
|
||||||
# cylinder r=1.5 along first line
|
# cylinder r=1.5 along first line
|
||||||
# then sweep allong arc from r=1.5 to r=1.0
|
# then sweep along arc from r=1.5 to r=1.0
|
||||||
# then cylinder r=1.0 along last line
|
# then cylinder r=1.0 along last line
|
||||||
arcSweep = (
|
arcSweep = (
|
||||||
cq.Workplane("YZ")
|
cq.Workplane("YZ")
|
||||||
|
@ -47,6 +47,11 @@ class TestCadObjects(BaseTest):
|
|||||||
v9.z = 3.0
|
v9.z = 3.0
|
||||||
self.assertTupleAlmostEquals((1, 2, 3), (v9.x, v9.y, v9.z), 4)
|
self.assertTupleAlmostEquals((1, 2, 3), (v9.x, v9.y, v9.z), 4)
|
||||||
|
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
Vector("vector")
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
Vector(1, 2, 3, 4)
|
||||||
|
|
||||||
def testVertex(self):
|
def testVertex(self):
|
||||||
"""
|
"""
|
||||||
Tests basic vertex functions
|
Tests basic vertex functions
|
||||||
@ -66,6 +71,46 @@ class TestCadObjects(BaseTest):
|
|||||||
# OCC uses some approximations
|
# OCC uses some approximations
|
||||||
self.assertAlmostEqual(bb1.xlen, 1.0, 1)
|
self.assertAlmostEqual(bb1.xlen, 1.0, 1)
|
||||||
|
|
||||||
|
# Test adding to an existing bounding box
|
||||||
|
v0 = Vertex.makeVertex(0, 0, 0)
|
||||||
|
bb2 = v0.BoundingBox().add(v.BoundingBox())
|
||||||
|
|
||||||
|
bb3 = bb1.add(bb2)
|
||||||
|
self.assertTupleAlmostEquals((2, 2, 2), (bb3.xlen, bb3.ylen, bb3.zlen), 7)
|
||||||
|
|
||||||
|
bb3 = bb2.add((3, 3, 3))
|
||||||
|
self.assertTupleAlmostEquals((3, 3, 3), (bb3.xlen, bb3.ylen, bb3.zlen), 7)
|
||||||
|
|
||||||
|
bb3 = bb2.add(Vector(3, 3, 3))
|
||||||
|
self.assertTupleAlmostEquals((3, 3, 3), (bb3.xlen, bb3.ylen, bb3.zlen), 7)
|
||||||
|
|
||||||
|
# Test 2D bounding boxes
|
||||||
|
bb1 = (
|
||||||
|
Vertex.makeVertex(1, 1, 0)
|
||||||
|
.BoundingBox()
|
||||||
|
.add(Vertex.makeVertex(2, 2, 0).BoundingBox())
|
||||||
|
)
|
||||||
|
bb2 = (
|
||||||
|
Vertex.makeVertex(0, 0, 0)
|
||||||
|
.BoundingBox()
|
||||||
|
.add(Vertex.makeVertex(3, 3, 0).BoundingBox())
|
||||||
|
)
|
||||||
|
bb3 = (
|
||||||
|
Vertex.makeVertex(0, 0, 0)
|
||||||
|
.BoundingBox()
|
||||||
|
.add(Vertex.makeVertex(1.5, 1.5, 0).BoundingBox())
|
||||||
|
)
|
||||||
|
# Test that bb2 contains bb1
|
||||||
|
self.assertEqual(bb2, BoundBox.findOutsideBox2D(bb1, bb2))
|
||||||
|
self.assertEqual(bb2, BoundBox.findOutsideBox2D(bb2, bb1))
|
||||||
|
# Test that neither bounding box contains the other
|
||||||
|
self.assertIsNone(BoundBox.findOutsideBox2D(bb1, bb3))
|
||||||
|
|
||||||
|
# Test creation of a bounding box from a shape - note the low accuracy comparison
|
||||||
|
# as the box is a little larger than the shape
|
||||||
|
bb1 = BoundBox._fromTopoDS(Solid.makeCylinder(1, 1).wrapped, optimal=False)
|
||||||
|
self.assertTupleAlmostEquals((2, 2, 1), (bb1.xlen, bb1.ylen, bb1.zlen), 1)
|
||||||
|
|
||||||
def testEdgeWrapperCenter(self):
|
def testEdgeWrapperCenter(self):
|
||||||
e = self._make_circle()
|
e = self._make_circle()
|
||||||
|
|
||||||
@ -295,6 +340,18 @@ class TestCadObjects(BaseTest):
|
|||||||
vec.Length * math.cos(angle), vecLineProjection.Length, decimal_places
|
vec.Length * math.cos(angle), vecLineProjection.Length, decimal_places
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def testVectorNotImplemented(self):
|
||||||
|
v = Vector(1, 2, 3)
|
||||||
|
with self.assertRaises(NotImplementedError):
|
||||||
|
v.distanceToLine()
|
||||||
|
with self.assertRaises(NotImplementedError):
|
||||||
|
v.distanceToPlane()
|
||||||
|
|
||||||
|
def testVectorSpecialMethods(self):
|
||||||
|
v = Vector(1, 2, 3)
|
||||||
|
self.assertEqual(repr(v), "Vector: (1.0, 2.0, 3.0)")
|
||||||
|
self.assertEqual(str(v), "Vector: (1.0, 2.0, 3.0)")
|
||||||
|
|
||||||
def testMatrixCreationAndAccess(self):
|
def testMatrixCreationAndAccess(self):
|
||||||
def matrix_vals(m):
|
def matrix_vals(m):
|
||||||
return [[m[r, c] for c in range(4)] for r in range(4)]
|
return [[m[r, c] for c in range(4)] for r in range(4)]
|
||||||
@ -339,7 +396,9 @@ class TestCadObjects(BaseTest):
|
|||||||
]
|
]
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
Matrix(invalid)
|
Matrix(invalid)
|
||||||
|
# Test input with invalid type
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
Matrix("invalid")
|
||||||
# Test input with invalid size / nested types
|
# Test input with invalid size / nested types
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
Matrix([[1, 2, 3, 4], [1, 2, 3], [1, 2, 3, 4]])
|
Matrix([[1, 2, 3, 4], [1, 2, 3], [1, 2, 3, 4]])
|
||||||
@ -359,6 +418,77 @@ class TestCadObjects(BaseTest):
|
|||||||
with self.assertRaises(IndexError):
|
with self.assertRaises(IndexError):
|
||||||
m["ab"]
|
m["ab"]
|
||||||
|
|
||||||
|
# test __repr__ methods
|
||||||
|
m = Matrix(vals4x4)
|
||||||
|
mRepr = "Matrix([[1.0, 0.0, 0.0, 1.0],\n [0.0, 1.0, 0.0, 2.0],\n [0.0, 0.0, 1.0, 3.0],\n [0.0, 0.0, 0.0, 1.0]])"
|
||||||
|
self.assertEqual(repr(m), mRepr)
|
||||||
|
self.assertEqual(str(eval(repr(m))), mRepr)
|
||||||
|
|
||||||
|
def testMatrixFunctionality(self):
|
||||||
|
# Test rotate methods
|
||||||
|
def matrix_almost_equal(m, target_matrix):
|
||||||
|
for r, row in enumerate(target_matrix):
|
||||||
|
for c, target_value in enumerate(row):
|
||||||
|
self.assertAlmostEqual(m[r, c], target_value)
|
||||||
|
|
||||||
|
root_3_over_2 = math.sqrt(3) / 2
|
||||||
|
m_rotate_x_30 = [
|
||||||
|
[1, 0, 0, 0],
|
||||||
|
[0, root_3_over_2, -1 / 2, 0],
|
||||||
|
[0, 1 / 2, root_3_over_2, 0],
|
||||||
|
[0, 0, 0, 1],
|
||||||
|
]
|
||||||
|
mx = Matrix()
|
||||||
|
mx.rotateX(30 * DEG2RAD)
|
||||||
|
matrix_almost_equal(mx, m_rotate_x_30)
|
||||||
|
|
||||||
|
m_rotate_y_30 = [
|
||||||
|
[root_3_over_2, 0, 1 / 2, 0],
|
||||||
|
[0, 1, 0, 0],
|
||||||
|
[-1 / 2, 0, root_3_over_2, 0],
|
||||||
|
[0, 0, 0, 1],
|
||||||
|
]
|
||||||
|
my = Matrix()
|
||||||
|
my.rotateY(30 * DEG2RAD)
|
||||||
|
matrix_almost_equal(my, m_rotate_y_30)
|
||||||
|
|
||||||
|
m_rotate_z_30 = [
|
||||||
|
[root_3_over_2, -1 / 2, 0, 0],
|
||||||
|
[1 / 2, root_3_over_2, 0, 0],
|
||||||
|
[0, 0, 1, 0],
|
||||||
|
[0, 0, 0, 1],
|
||||||
|
]
|
||||||
|
mz = Matrix()
|
||||||
|
mz.rotateZ(30 * DEG2RAD)
|
||||||
|
matrix_almost_equal(mz, m_rotate_z_30)
|
||||||
|
|
||||||
|
# Test matrix multipy vector
|
||||||
|
v = Vector(1, 0, 0)
|
||||||
|
self.assertTupleAlmostEquals(
|
||||||
|
mz.multiply(v).toTuple(), (root_3_over_2, 1 / 2, 0), 7
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test matrix multipy matrix
|
||||||
|
m_rotate_xy_30 = [
|
||||||
|
[root_3_over_2, 0, 1 / 2, 0],
|
||||||
|
[1 / 4, root_3_over_2, -root_3_over_2 / 2, 0],
|
||||||
|
[-root_3_over_2 / 2, 1 / 2, 3 / 4, 0],
|
||||||
|
[0, 0, 0, 1],
|
||||||
|
]
|
||||||
|
mxy = mx.multiply(my)
|
||||||
|
matrix_almost_equal(mxy, m_rotate_xy_30)
|
||||||
|
|
||||||
|
# Test matrix inverse
|
||||||
|
vals4x4 = [[1, 2, 3, 4], [5, 1, 6, 7], [8, 9, 1, 10], [0, 0, 0, 1]]
|
||||||
|
vals4x4_invert = [
|
||||||
|
[-53 / 144, 25 / 144, 1 / 16, -53 / 144],
|
||||||
|
[43 / 144, -23 / 144, 1 / 16, -101 / 144],
|
||||||
|
[37 / 144, 7 / 144, -1 / 16, -107 / 144],
|
||||||
|
[0, 0, 0, 1],
|
||||||
|
]
|
||||||
|
m = Matrix(vals4x4).inverse()
|
||||||
|
matrix_almost_equal(m, vals4x4_invert)
|
||||||
|
|
||||||
def testTranslate(self):
|
def testTranslate(self):
|
||||||
e = Edge.makeCircle(2, (1, 2, 3))
|
e = Edge.makeCircle(2, (1, 2, 3))
|
||||||
e2 = e.translate(Vector(0, 0, 1))
|
e2 = e.translate(Vector(0, 0, 1))
|
||||||
@ -413,6 +543,55 @@ class TestCadObjects(BaseTest):
|
|||||||
Plane(origin=(0, 0, 0), xDir=(1, 0, 0), normal=(0, 1, 1)),
|
Plane(origin=(0, 0, 0), xDir=(1, 0, 0), normal=(0, 1, 1)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def testInvalidPlane(self):
|
||||||
|
# Test plane creation error handling
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
Plane.named("XX", (0, 0, 0))
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
Plane(origin=(0, 0, 0), xDir=(0, 0, 0), normal=(0, 1, 1))
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
Plane(origin=(0, 0, 0), xDir=(1, 0, 0), normal=(0, 0, 0))
|
||||||
|
|
||||||
|
def testPlaneMethods(self):
|
||||||
|
# Test error checking
|
||||||
|
p = Plane(origin=(0, 0, 0), xDir=(1, 0, 0), normal=(0, 1, 0))
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
p.toLocalCoords("box")
|
||||||
|
with self.assertRaises(NotImplementedError):
|
||||||
|
p.mirrorInPlane([Solid.makeBox(1, 1, 1)], "Z")
|
||||||
|
|
||||||
|
# Test translation to local coordinates
|
||||||
|
local_box = Workplane(p.toLocalCoords(Solid.makeBox(1, 1, 1)))
|
||||||
|
local_box_vertices = [(v.X, v.Y, v.Z) for v in local_box.vertices().vals()]
|
||||||
|
target_vertices = [
|
||||||
|
(0, -1, 0),
|
||||||
|
(0, 0, 0),
|
||||||
|
(0, -1, 1),
|
||||||
|
(0, 0, 1),
|
||||||
|
(1, -1, 0),
|
||||||
|
(1, 0, 0),
|
||||||
|
(1, -1, 1),
|
||||||
|
(1, 0, 1),
|
||||||
|
]
|
||||||
|
for i, target_point in enumerate(target_vertices):
|
||||||
|
self.assertTupleAlmostEquals(target_point, local_box_vertices[i], 7)
|
||||||
|
|
||||||
|
# Test mirrorInPlane
|
||||||
|
mirror_box = Workplane(p.mirrorInPlane([Solid.makeBox(1, 1, 1)], "Y")[0])
|
||||||
|
mirror_box_vertices = [(v.X, v.Y, v.Z) for v in mirror_box.vertices().vals()]
|
||||||
|
target_vertices = [
|
||||||
|
(0, 0, 1),
|
||||||
|
(0, 0, 0),
|
||||||
|
(0, -1, 1),
|
||||||
|
(0, -1, 0),
|
||||||
|
(-1, 0, 1),
|
||||||
|
(-1, 0, 0),
|
||||||
|
(-1, -1, 1),
|
||||||
|
(-1, -1, 0),
|
||||||
|
]
|
||||||
|
for i, target_point in enumerate(target_vertices):
|
||||||
|
self.assertTupleAlmostEquals(target_point, mirror_box_vertices[i], 7)
|
||||||
|
|
||||||
def testLocation(self):
|
def testLocation(self):
|
||||||
|
|
||||||
# Vector
|
# Vector
|
||||||
@ -437,6 +616,17 @@ class TestCadObjects(BaseTest):
|
|||||||
== loc3.wrapped.Transformation().TranslationPart().Z()
|
== loc3.wrapped.Transformation().TranslationPart().Z()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Test creation from the OCP.gp.gp_Trsf object
|
||||||
|
loc4 = Location(gp_Trsf())
|
||||||
|
self.assertTupleAlmostEquals(loc4.toTuple()[0], (0, 0, 0), 7)
|
||||||
|
self.assertTupleAlmostEquals(loc4.toTuple()[1], (0, 0, 0), 7)
|
||||||
|
|
||||||
|
# Test error handling on creation
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
Location((0, 0, 1))
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
Location("xy_plane")
|
||||||
|
|
||||||
def testEdgeWrapperRadius(self):
|
def testEdgeWrapperRadius(self):
|
||||||
|
|
||||||
# get a radius from a simple circle
|
# get a radius from a simple circle
|
||||||
|
@ -55,7 +55,7 @@ TEST_RESULT_TEMPLATE = """
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# clean up any summary file that is in the output directory.
|
# clean up any summary file that is in the output directory.
|
||||||
# i know, this sux, but there is no other way to do this in 2.6, as we cannot do class fixutres till 2.7
|
# i know, this sux, but there is no other way to do this in 2.6, as we cannot do class fixtures till 2.7
|
||||||
writeStringToFile(SUMMARY_TEMPLATE, SUMMARY_FILE)
|
writeStringToFile(SUMMARY_TEMPLATE, SUMMARY_FILE)
|
||||||
|
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ class TestCadQuery(BaseTest):
|
|||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
"""
|
"""
|
||||||
Update summary with data from this test.
|
Update summary with data from this test.
|
||||||
This is a really hackey way of doing it-- we get a startup event from module load,
|
This is a really hacky way of doing it-- we get a startup event from module load,
|
||||||
but there is no way in unittest to get a single shutdown event-- except for stuff in 2.7 and above
|
but there is no way in unittest to get a single shutdown event-- except for stuff in 2.7 and above
|
||||||
|
|
||||||
So what we do here is to read the existing file, stick in more content, and leave it
|
So what we do here is to read the existing file, stick in more content, and leave it
|
||||||
@ -187,7 +187,7 @@ class TestCadQuery(BaseTest):
|
|||||||
"""
|
"""
|
||||||
Tests a plugin to make regular polygons around points on the stack
|
Tests a plugin to make regular polygons around points on the stack
|
||||||
|
|
||||||
Demonstratings using eachpoint to allow working in local coordinates
|
Demonstrations using eachpoint to allow working in local coordinates
|
||||||
to create geometry
|
to create geometry
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -716,7 +716,7 @@ class TestCadQuery(BaseTest):
|
|||||||
.consolidateWires()
|
.consolidateWires()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test point equivalence for parameter, and pamater multiplied by 10:
|
# Test point equivalence for parameter, and parameter multiplied by 10:
|
||||||
test_point1 = spline1.edges().val().positionAt(1.5, mode="parameter")
|
test_point1 = spline1.edges().val().positionAt(1.5, mode="parameter")
|
||||||
test_point2 = spline2.edges().val().positionAt(15, mode="parameter")
|
test_point2 = spline2.edges().val().positionAt(15, mode="parameter")
|
||||||
expected_test_point = Vector(1.625, 0.625, 0.0)
|
expected_test_point = Vector(1.625, 0.625, 0.0)
|
||||||
@ -880,7 +880,7 @@ class TestCadQuery(BaseTest):
|
|||||||
start = ellipseArc3.vertices().objects[0]
|
start = ellipseArc3.vertices().objects[0]
|
||||||
end = ellipseArc3.vertices().objects[1]
|
end = ellipseArc3.vertices().objects[1]
|
||||||
|
|
||||||
# swap start and end points for coparison due to different sense
|
# swap start and end points for comparison due to different sense
|
||||||
self.assertTupleAlmostEquals(
|
self.assertTupleAlmostEquals(
|
||||||
(start.X, start.Y), (p0[0] + ex_rot, p0[1] + ey_rot), 3
|
(start.X, start.Y), (p0[0] + ex_rot, p0[1] + ey_rot), 3
|
||||||
)
|
)
|
||||||
@ -909,7 +909,7 @@ class TestCadQuery(BaseTest):
|
|||||||
start = ellipseArc4.vertices().objects[0]
|
start = ellipseArc4.vertices().objects[0]
|
||||||
end = ellipseArc4.vertices().objects[1]
|
end = ellipseArc4.vertices().objects[1]
|
||||||
|
|
||||||
# swap start and end points for coparison due to different sense
|
# swap start and end points for comparison due to different sense
|
||||||
self.assertTupleAlmostEquals(
|
self.assertTupleAlmostEquals(
|
||||||
(start.X, start.Y), (p0[0] + ex_rot - ex_rot, p0[1] + ey_rot - ey_rot), 3
|
(start.X, start.Y), (p0[0] + ex_rot - ex_rot, p0[1] + ey_rot - ey_rot), 3
|
||||||
)
|
)
|
||||||
@ -1146,7 +1146,7 @@ class TestCadQuery(BaseTest):
|
|||||||
.sweep(path, multisection=True)
|
.sweep(path, multisection=True)
|
||||||
)
|
)
|
||||||
|
|
||||||
# We can sweep thrue different shapes
|
# We can sweep through different shapes
|
||||||
recttocircleSweep = (
|
recttocircleSweep = (
|
||||||
Workplane("YZ")
|
Workplane("YZ")
|
||||||
.workplane(offset=-10.0)
|
.workplane(offset=-10.0)
|
||||||
@ -1193,7 +1193,7 @@ class TestCadQuery(BaseTest):
|
|||||||
|
|
||||||
# Placement of different shapes should follow the path
|
# Placement of different shapes should follow the path
|
||||||
# cylinder r=1.5 along first line
|
# cylinder r=1.5 along first line
|
||||||
# then sweep allong arc from r=1.5 to r=1.0
|
# then sweep along arc from r=1.5 to r=1.0
|
||||||
# then cylinder r=1.0 along last line
|
# then cylinder r=1.0 along last line
|
||||||
arcSweep = (
|
arcSweep = (
|
||||||
Workplane("YZ")
|
Workplane("YZ")
|
||||||
@ -1483,10 +1483,10 @@ class TestCadQuery(BaseTest):
|
|||||||
self.assertEqual(0, s.faces().size())
|
self.assertEqual(0, s.faces().size())
|
||||||
|
|
||||||
t = r.faces(">Z").workplane().rect(0.25, 0.25).extrude(0.5, False)
|
t = r.faces(">Z").workplane().rect(0.25, 0.25).extrude(0.5, False)
|
||||||
# result has 6 faces, becuase it was not combined with the original
|
# result has 6 faces, because it was not combined with the original
|
||||||
self.assertEqual(6, t.faces().size())
|
self.assertEqual(6, t.faces().size())
|
||||||
self.assertEqual(6, r.faces().size()) # original is unmodified as well
|
self.assertEqual(6, r.faces().size()) # original is unmodified as well
|
||||||
# subseuent opertions use that context solid afterwards
|
# subsequent operations use that context solid afterwards
|
||||||
|
|
||||||
def testSimpleWorkplane(self):
|
def testSimpleWorkplane(self):
|
||||||
"""
|
"""
|
||||||
@ -1794,7 +1794,7 @@ class TestCadQuery(BaseTest):
|
|||||||
self.saveModel(t)
|
self.saveModel(t)
|
||||||
|
|
||||||
def testBasicLines(self):
|
def testBasicLines(self):
|
||||||
"Make a triangluar boss"
|
"Make a triangular boss"
|
||||||
global OUTDIR
|
global OUTDIR
|
||||||
s = Workplane(Plane.XY())
|
s = Workplane(Plane.XY())
|
||||||
|
|
||||||
@ -2443,6 +2443,39 @@ class TestCadQuery(BaseTest):
|
|||||||
self.assertEqual(1, s.solids().size())
|
self.assertEqual(1, s.solids().size())
|
||||||
self.assertEqual(4, s.faces().size())
|
self.assertEqual(4, s.faces().size())
|
||||||
|
|
||||||
|
def testCylinderDefaults(self):
|
||||||
|
s = Workplane("XY").cylinder(20, 10)
|
||||||
|
self.assertEqual(1, s.size())
|
||||||
|
self.assertEqual(1, s.solids().size())
|
||||||
|
self.assertEqual(3, s.faces().size())
|
||||||
|
self.assertEqual(2, s.vertices().size())
|
||||||
|
self.assertTupleAlmostEquals(s.val().Center().toTuple(), (0, 0, 0), 3)
|
||||||
|
|
||||||
|
def testCylinderCentering(self):
|
||||||
|
radius = 10
|
||||||
|
height = 40
|
||||||
|
b = (True, False)
|
||||||
|
expected_x = (0, radius)
|
||||||
|
expected_y = (0, radius)
|
||||||
|
expected_z = (0, height / 2)
|
||||||
|
for (xopt, xval), (yopt, yval), (zopt, zval) in product(
|
||||||
|
zip(b, expected_x), zip(b, expected_y), zip(b, expected_z)
|
||||||
|
):
|
||||||
|
s = Workplane("XY").cylinder(height, radius, centered=(xopt, yopt, zopt))
|
||||||
|
self.assertEqual(1, s.size())
|
||||||
|
self.assertTupleAlmostEquals(
|
||||||
|
s.val().Center().toTuple(), (xval, yval, zval), 3
|
||||||
|
)
|
||||||
|
# check centered=True produces the same result as centered=(True, True, True)
|
||||||
|
for val in b:
|
||||||
|
s0 = Workplane("XY").cylinder(height, radius, centered=val)
|
||||||
|
self.assertEqual(s0.size(), 1)
|
||||||
|
s1 = Workplane("XY").cylinder(height, radius, centered=(val, val, val))
|
||||||
|
self.assertEqual(s1.size(), 1)
|
||||||
|
self.assertTupleAlmostEquals(
|
||||||
|
s0.val().Center().toTuple(), s1.val().Center().toTuple(), 3
|
||||||
|
)
|
||||||
|
|
||||||
def testWedgeDefaults(self):
|
def testWedgeDefaults(self):
|
||||||
s = Workplane("XY").wedge(10, 10, 10, 5, 5, 5, 5)
|
s = Workplane("XY").wedge(10, 10, 10, 5, 5, 5, 5)
|
||||||
self.saveModel(s)
|
self.saveModel(s)
|
||||||
@ -2954,7 +2987,7 @@ class TestCadQuery(BaseTest):
|
|||||||
return cup
|
return cup
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# for some reason shell doesnt work on this simple shape. how disappointing!
|
# for some reason shell doesn't work on this simple shape. how disappointing!
|
||||||
td = 50.0
|
td = 50.0
|
||||||
bd = 20.0
|
bd = 20.0
|
||||||
h = 10.0
|
h = 10.0
|
||||||
@ -2990,7 +3023,7 @@ class TestCadQuery(BaseTest):
|
|||||||
|
|
||||||
# How far in from the edges the screwposts should be place.
|
# How far in from the edges the screwposts should be place.
|
||||||
p_screwpostInset = 12.0
|
p_screwpostInset = 12.0
|
||||||
# nner Diameter of the screwpost holes, should be roughly screw diameter not including threads
|
# Inner Diameter of the screwpost holes, should be roughly screw diameter not including threads
|
||||||
p_screwpostID = 4.0
|
p_screwpostID = 4.0
|
||||||
# Outer Diameter of the screwposts.\nDetermines overall thickness of the posts
|
# Outer Diameter of the screwposts.\nDetermines overall thickness of the posts
|
||||||
p_screwpostOD = 10.0
|
p_screwpostOD = 10.0
|
||||||
@ -3427,7 +3460,7 @@ class TestCadQuery(BaseTest):
|
|||||||
|
|
||||||
def testWorkplaneCenterOptions(self):
|
def testWorkplaneCenterOptions(self):
|
||||||
"""
|
"""
|
||||||
Test options for specifiying origin of workplane
|
Test options for specifying origin of workplane
|
||||||
"""
|
"""
|
||||||
decimal_places = 9
|
decimal_places = 9
|
||||||
|
|
||||||
@ -3544,7 +3577,7 @@ class TestCadQuery(BaseTest):
|
|||||||
self.assertEqual(len(r.objects), 2)
|
self.assertEqual(len(r.objects), 2)
|
||||||
self.assertTrue(isinstance(r.val(), Solid))
|
self.assertTrue(isinstance(r.val(), Solid))
|
||||||
|
|
||||||
# find solid should return a compund of two solids
|
# find solid should return a compound of two solids
|
||||||
s = r.findSolid()
|
s = r.findSolid()
|
||||||
self.assertEqual(len(s.Solids()), 2)
|
self.assertEqual(len(s.Solids()), 2)
|
||||||
self.assertTrue(isinstance(s, Compound))
|
self.assertTrue(isinstance(s, Compound))
|
||||||
@ -3763,7 +3796,7 @@ class TestCadQuery(BaseTest):
|
|||||||
|
|
||||||
def test_interpPlate(self):
|
def test_interpPlate(self):
|
||||||
"""
|
"""
|
||||||
Tests the interpPlate() functionnalites
|
Tests the interpPlate() functionalities
|
||||||
Numerical values of Areas and Volumes were obtained with the Area() and Volume() functions on a Linux machine under Debian 10 with python 3.7.
|
Numerical values of Areas and Volumes were obtained with the Area() and Volume() functions on a Linux machine under Debian 10 with python 3.7.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ class TestCQGI(BaseTest):
|
|||||||
def test_that_invalid_syntax_in_script_fails_immediately(self):
|
def test_that_invalid_syntax_in_script_fails_immediately(self):
|
||||||
badscript = textwrap.dedent(
|
badscript = textwrap.dedent(
|
||||||
"""
|
"""
|
||||||
this doesnt even compile
|
this doesn't even compile
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@ import io
|
|||||||
from cadquery import *
|
from cadquery import *
|
||||||
from cadquery import exporters, importers
|
from cadquery import exporters, importers
|
||||||
from tests import BaseTest
|
from tests import BaseTest
|
||||||
|
from OCP.GeomConvert import GeomConvert
|
||||||
|
from OCP.BRepBuilderAPI import BRepBuilderAPI_MakeEdge
|
||||||
|
|
||||||
|
|
||||||
class TestExporters(BaseTest):
|
class TestExporters(BaseTest):
|
||||||
@ -168,6 +170,43 @@ class TestExporters(BaseTest):
|
|||||||
self.assertAlmostEqual(s4.val().Area(), s4_i.val().Area(), 6)
|
self.assertAlmostEqual(s4.val().Area(), s4_i.val().Area(), 6)
|
||||||
self.assertAlmostEqual(s4.edges().size(), s4_i.edges().size())
|
self.assertAlmostEqual(s4.edges().size(), s4_i.edges().size())
|
||||||
|
|
||||||
|
# test periodic spline
|
||||||
|
w = Workplane().spline([(1, 1), (2, 2), (3, 2), (3, 1)], periodic=True)
|
||||||
|
exporters.dxf.exportDXF(w, "res5.dxf")
|
||||||
|
|
||||||
|
w_i = importers.importDXF("res5.dxf")
|
||||||
|
|
||||||
|
self.assertAlmostEqual(w.val().Length(), w_i.wires().val().Length(), 6)
|
||||||
|
|
||||||
|
# test rational spline
|
||||||
|
c = Edge.makeCircle(1)
|
||||||
|
adaptor = c._geomAdaptor()
|
||||||
|
curve = GeomConvert.CurveToBSplineCurve_s(adaptor.Curve().Curve())
|
||||||
|
|
||||||
|
e = Workplane().add(Edge(BRepBuilderAPI_MakeEdge(curve).Shape()))
|
||||||
|
exporters.dxf.exportDXF(e, "res6.dxf")
|
||||||
|
|
||||||
|
e_i = importers.importDXF("res6.dxf")
|
||||||
|
|
||||||
|
self.assertAlmostEqual(e.val().Length(), e_i.wires().val().Length(), 6)
|
||||||
|
|
||||||
|
# test non-planar section
|
||||||
|
s5 = (
|
||||||
|
Workplane()
|
||||||
|
.spline([(0, 0), (1, 0), (1, 1), (0, 1)])
|
||||||
|
.close()
|
||||||
|
.extrude(1, both=True)
|
||||||
|
.translate((-3, -4, 0))
|
||||||
|
)
|
||||||
|
|
||||||
|
s5.plane = Plane(origin=(0, 0.1, 0.5), normal=(0.05, 0.05, 1))
|
||||||
|
s5 = s5.section()
|
||||||
|
exporters.dxf.exportDXF(s5, "res7.dxf")
|
||||||
|
|
||||||
|
s5_i = importers.importDXF("res7.dxf")
|
||||||
|
|
||||||
|
self.assertAlmostEqual(s5.val().Area(), s5_i.val().Area(), 4)
|
||||||
|
|
||||||
def testTypeHandling(self):
|
def testTypeHandling(self):
|
||||||
|
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
|
Reference in New Issue
Block a user